反射简介
反射概念 : 反射是对象的反向处理操作 既根据对象来获取对象的来源信息 既对象所属类 反射多用于框架等
三种实例化对象
Class类是描述整个类的概念,也是整个反射的源头,当类在JVM中被运行的时候 会产生唯一的.Class字节码 通过Class对象找到当前类的信息 在使用Class类的时候关注的依然是这个类的对象 Class类的对象产生方式有三种
1.任何类的实例化对象可以通过Object类中的getClass()方法取得Class类对象
2.“类.class”直接根据某个具体的类取得Class类的实例化对象
3.使用Class提供的方法public static Class<?> forName(String className) throws ClassNotFoundException
通过观察这三个方法发现只有第一个方法才用到实例化对象 而其他两个都不会用到实例化对象 所以可以用反射实例化对象 方法是Class类提供的 public T newInstance() 所以取得Class对象就意味着取得了一个指定类的操作权
Class类通过反射实例化类对象的时候,只能够调用类中的无参构造。如果现在类中没有无参构造则无法使用Class
类调用,只能够通过明确的构造调用实例化处理
反射与类操作
反射调用构造方法
取得指定参数类型的构造
public Constructor<T> getConstructor(class<?>...parameterTypes)
取得类中所有的构造方法
public Constructor<?> getConstructors()
反射调用普通方法
取得所有的普通方法
public Method[] getMethods()
取得指定的普通方法
public Method getMethod(String name ,class<?>...parameterTypes)
调用类中方法
public Object invoke(Object obj,object...args)
示例:调用setter getter方法
public class Test {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("www.angda.java.testthread.Person") ;
// 任何时候调用类中的普通方法都必须有实例化对象
Object obj = cls.newInstance() ;
// 取得setName这个方法的实例化对象,设置方法名称与参数类型
Method setMethod = cls.getMethod("setName", String.class) ;
// 随后需要通过Method类对象调用指定的方法,调用方法需要有实例化对象
// 同时传入参数
setMethod.invoke(obj, "yuisama") ; // 相当于Person对象.setName("yuisama") ;
Method getMethod = cls.getMethod("getName") ;
Object result = getMethod.invoke(obj) ; // 相当于Person对象.getName() ;
System.out.println(result) ;
}
}
反射调用类中属性
获取本类中所有属性
public Field[] getDeclaredFields()
取得本类中指定的属性
public Method getDeclaredMethod(String name, Class<?>… parameterTypes)
父类中全部属性
public Field[] getFields() throws SecurityException
父类中指定属性
public Field getField(String name)
属性的核心描述类中有两个重要的方法为set 和 get操作属性
class Person {
private String name ;
}
public class Test {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("www.angda.java.testthread.Person") ;
// 实例化本类对象
Object obj = cls.newInstance() ;
// 操作name属性
Field nameField = cls.getDeclaredField("name") ;
nameField.set(obj, "angda") ; // 相当于对象.name = "angda"
System.out.println(nameField.get(obj)); // 取得属性
}
}