设计模式
build
factory
反射
Java中主要由以下的类来实现Java反射机制(这些类都位于java.lang.reflect包中):
Class 对象是在加载类时由 Java 虚拟机自动构造
- Class类:代表一个类。
- Field类:代表类的成员变量(成员变量也称为类的属性)。
- Method类:代表类的方法。
- Constructor类:代表类的构造方法。
- Array类:提供了动态创建数组,以及访问数组的元素的静态方法。
获取class
Class.forName() 常用
Hero.class
new Hero().getClass()
Class常用API
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。
getConstrutors():获得类的public类型的构造方法。
getConstrutor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
Field 常用API
1、 public Class<?>getDeclaringClass()
返回表示类或接口的 Class 对象,该类或接口声明由此Field 对象表示的字段。
指定者:接口Member 中的getDeclaringClass
返回:表示声明底层成员的类的对象
2、publicStringgetName()
返回此Field 对象表示的字段的名称。
指定者:接口Member 中的getName
返回:底层成员的简单名称
3、public Class<?>getType() 返回一个Class 对象,它标识了此 Field 对象所表示字段的声明类型。
返回:标识此对象所表示字段的声明类型的 Class 对象
4、public StringtoString()
返回一个描述此 Field 的字符串。
格式是:该字段(如果存在的话)的访问修饰符,后面跟着字段类型和一个空格,再后面是声明该字段的类的完全限定名,后面跟着一个句点,最后是字段的名称。例如:
5、public boolean equals(Object obj)
将此 Field 与指定对象比较。如果对象是相同的,则返回 true。如果由相同的类声明并且具有相同的名称和类型,那么这两个Field 对象是相同的。
覆盖:类 Object 中的equals
参数:obj - 要与之比较的引用对象。
返回:如果此对象与 obj 参数相同,则返回 true;否则返回false。
Mehted 常用API
1、Method对象的获取 方法所在类的类对象.getMethod(String methodName,Class[] argsClass);
获取方法Method对象的参数是方法名和方法的参数类。
2、method.invoke(方法所在类的对象,Object[] args);
执行方法参数:方法所在类的实例对象,和实际参数的Object数组;
如果该方法是静态方法,则方法所在类的对象可以为null
PropertyDescriptor
PropertyDescriptor对象是位于java.beans包下的工具类,顾名思义为属性描述器,通常我们用于通过反射获取对象方法的时候,下面来看一下常用的用法吧!
创建
public PropertyDescriptor(String propertyName, Class<?> beanClass)
属性名字,Class对象
常用api
prop.getName() 获取属性编码
prop.getReadMethod() 获取get方法
prop.getWriteMethod() 获取set方法
prop.getPropertyType() 获取属性的定义类型
创建对象
1.获取类对象 Class class = Class.forName("pojo.Hero");
2.获取构造器对象 Constructor con = clazz.getConstructor(形参.class);
Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
3 获取对象 Hero hero =con.newInstance(实参);
获取成员变量并使用
1.获取HeroPlus类的对象
2. 获取属性 Field f1 = h.getDeclaredField("属性名")
3. 修改属性 f1.set(h,实参),注意这里的h是对象,不是类对象
执行对象方法
// invoke第一个参数表示执行哪个对象的方法,剩下的参数是执行方法时需要传入的参数
method = clazz.getDeclaredMethod("setAge", Integer.class);
Object obje = clazz.newInstance();
method.invoke(obje,2);
获取对象字段值
//通过Class对象.getDeclaredField(name)获取字段对象
Field declaredField = paramtertypeClass.getDeclaredField(content);
//暴力访问 获取值
declaredField.setAccessible(true);
//Field.get(Objcet) 来获取到objcet里面field字段的值
Object o = declaredField.get(user);
赋值给对象
User user =new User();
PropertyDescriptor pro = new PropertyDescriptor("id",User.Class);
Mehted wri = pro.getWriteMethod()
writeMethod.invoke(o,value);
泛型
常用的通配符有
T,E,K,V分别表示类型、元素、键、值
可变参
* 前提:方法的参数数据类型确定,参数的个数任意
* 可变参的语法个数:数据类型…变量名
* 可变参数本质上就是一个数组
dom4j
获取xml对象
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(filename)); // 读取XML文件,获得document对象
代理模式
简单理解:去火车站买票太远了,所以就在网上购买。网上和火车站都实现了卖票的接口,这个时候使用网上代理火车站买票会很方便
实现
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
2.创建被代理的类以及接口
3.通过Proxy的静态方法
newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理
4.通过代理调用方法
简单代码
//通过多态获取代理类
Subject realSubject = new RealSubject();
/**
* InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
* 其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用.
* 即:要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法
*/
InvocationHandler handler = new InvocationHandlerImpl(realSubject);
ClassLoader loader = realSubject.getClass().getClassLoader();
Class[] interfaces = realSubject.getClass().getInterfaces();
/**
* 该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
*/
Subject subject = (Subject) Proxy.newProxyInstance(loader, interfaces, handler);
System.out.println("动态代理对象的类型:"+subject.getClass().getName());
String hello = subject.SayHello("jiankunking");
Mybaties实现
public <T> T getMapper(Class<T> MapperClass) throws Exception {
Proxy.newProxyInstance(MapperClass.getClassLoader(), MapperClass.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//在这里写入代理代码
//组装Id
String methodName = method.getName();
String className = MapperClass.getName();
String id=className+"."+methodName;
//然后判断执行的啥方法
switch(className){
}
}
});
return null;
}