java反射机制
反射
反射就是把java类中的各种成分映射成一个个的Java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
(其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)
反射的使用
获取class对象的三种方式
- Class 类的实例表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有N多的实例每个类都有该Class对象。(包括基本数据类型)Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。
public static void main(String[] args) {
//第一种方式获取Class对象
Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
Class stuClass = stu1.getClass();//获取Class对象
System.out.println(stuClass.getName());
//第二种方式获取Class对象
Class stuClass2 = Student.class;
System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
//第三种方式获取Class对象
try {
Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//第四种获取class对象
ClassLoader classLoader = this.getClass().getClassLoader(); // 获取当前类的类加载器
Class clazz4 = classLoader.loadClass("com.atguigu.javase.reflect.Teacher");
Class superclass = clazz.getSuperclass(); // 获取父类class
Class[] interfaces = clazz.getInterfaces(); // 获取所有接口class
Field[] declaredFields = clazz.getDeclaredFields(); // 获取所有属性
Method[] declaredMethods = clazz.getDeclaredMethods(); // 获取所有方法对象
Method[] methods = clazz.getMethods();//获取所有的公共方法
getMethod可以获取本类及父类继承的公共方法
Method method = clazz.getDeclaredMethod("lesson", String.class, int.class); // 方法调用,方法名是必须的, 形参列表可选
method.setAccessible(true);突破私有化
}
通过反射创建对象
//Class clazz = Class.forName("类的全限定名称");
try {
// 软编码, 把编译错误转换成运行时异常!!
Class clazz = Class.forName("com.atguigu.javase.reflect.Teacher");// 手工加载类
Object object = clazz.newInstance(); // 通过类模板创建实体对象, 相当于new Teacher()
System.out.println(object);
} catch (ClassNotFoundException e) { // 类名错误, 或类没有找到
e.printStackTrace();
} catch (InstantiationException e) { // 找不到构造器
e.printStackTrace();
} catch (IllegalAccessException e) { // 非法访问时, 如果访问的目标是私有的.
e.printStackTrace();
}
}
调用构造器获取对象
// 构造器的获取必须要给定形参类型列表
Constructor<?> constructor = clazz.getConstructor(String.class, int.class, String.class); // 形参的数据类型列表
// new Teacher("佟刚", 40, "男");
Object object = constructor.newInstance("佟刚", 40, "男"); // 方法调用时给定实参, 实参必须和形参匹配
Constructor<?> constructor2 = clazz.getConstructor(); // 获取无参构造器
Object object2 = constructor2.newInstance();
获取类中的属性
Field nameField = clazz.getDeclaredField("name"); // 从类模板中获取声明的属性, 包括本类中的任意属性, 私有的也可以.
nameField.setAccessible(true); // 设置属性为可访问, 突破封装,私有化
nameField.set(object1, "佟刚");//等效于 object.name = "佟刚";
System.out.println(nameField.get(object1)); // System.out.println(object.name)
反射获取在类上的注解
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnn {
String value() default "缺省值";
}
@MyAnn("张三")
class Teacher implements Serializable
Class clazz = Class.forName("com.atguigu.javase.reflect.Teacher");
MyAnn annotation = (MyAnn)clazz.getAnnotation(MyAnn.class); // 获取类上使用的注解
System.out.println(annotation);
String value = annotation.value();

浙公网安备 33010602011771号