反射
在运行状态中,获取任意一个类的结构,创建对象,得到方法,执行方法,属性。
类加载
三种类加载器:
- BoostrapClassLoader引导启动类加载器;使用C++编写主要加载/lib的类库,无法被应用直接应用。
- ExtensionClassLoader扩展类加载器;主要加载/lib/ext类库
- ApplicationClassLoader应用类加载器;加载classpath目录下的所有jar和class文件。
双亲委派、
进行类加载时,会转发类加载请求到父类加载器,当父类加载器范围内没有这个类时反馈给子类进行加载。(避免重复加载)。
反射中的构造方法
//加载类得到类对象
Class<User> aClass = (Class<User>) Class.forName("reflect.User");
//找到无参数构造方法
Constructor<User> constructor = aClass.getConstructor();
//使用公开无参数构造方法,创建对象
User user = constructor.newInstance();
//使用有公开参数构造方法获得有参数对象
// Constructor<User> constructor1 = aClass.getConstructor(new Class[]{String.class, String.class});
// user = constructor1.newInstance("name", "sex");
//获取所有权限的构造方法
Constructor<User> declaredConstructor1 = aClass.getDeclaredConstructor();
//获取所有权限的构造方法数组
Constructor<User> declaredConstructor = aClass.getDeclaredConstructor(new Class[]{String.class, String.class});
//忽略权限检查
declaredConstructor.setAccessible(true);
user = declaredConstructor.newInstance("yse", "nan");
System.out.println(user.toString());
反射中调用方法
//加载类
Class<User> aClass =(Class<User>) Class.forName("reflect.User");
//获取类的构造方法
Constructor<User> declaredConstructor = aClass.getDeclaredConstructor();
//创建对象
User user = declaredConstructor.newInstance();
//通过反射获取类的方法:参数1.方法名,2.传入参数属性
Method setName = aClass.getMethod("setName",String.class);
//1.哪个对象需要调用,2.传递的参数
setName.invoke(user,"帅哥");
System.out.println(user.toString());
//获取所有权限的方法
Method setSex = aClass.getDeclaredMethod("setSex", String.class);
//允许私有访问
setSex.setAccessible(true);
//方法调用
setSex.invoke(user,"男");
System.out.println(user.toString());
反射得到类的属性
//加载类
Class<User> aClass = (Class<User>) Class.forName("reflect.User");
//获取无参数构造
Constructor<User> constructor = aClass.getConstructor();
//获得对象
User user = constructor.newInstance();
//获得所有权限的属性(属性名)
Field number = aClass.getDeclaredField("number");
//可以访问私有权限
number.setAccessible(true);
//1.需要改属性的对象。2.改的参数
number.set(user,123);
System.out.println(user.toString());
反射操作注解
//加载类
Class aClass = Class.forName("annotation.Book");
//获得注解类
TableAnnotation annotation =(TableAnnotation) aClass.getAnnotation(TableAnnotation.class);
//获取所有权限属性
Field[] fields = aClass.getDeclaredFields();
for (Field f:fields) {
//获取属性对应的注解
ColumnAnnotation annotation1 = f.getAnnotation(ColumnAnnotation.class);
System.out.println(f.getName()+annotation1.columnName());
}
内省-基于反射延伸的api(Instospector)
Bean类:
- 拥有无参数构造器
- 所有属性私有并提供get/set方法
- 实现了序列化接口
获取get和set方法
public static void main(String[] args) throws IntrospectionException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class c = User.class;
BeanInfo beanInfo = Introspector.getBeanInfo(c);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor p : propertyDescriptors) {
Method readMethod = p.getReadMethod();
Method writeMethod = p.getWriteMethod();
System.out.println(readMethod);
System.out.println(writeMethod);
}
}
运行结果
public final native java.lang.Class java.lang.Object.getClass()
null
public boolean fx.User.isFlag()
public void fx.User.setFlag(boolean)
public java.lang.String fx.User.getName()
public void fx.User.setName(java.lang.String)
public java.lang.String fx.User.getSex()
public void fx.User.setSex(java.lang.String)