反射
1.什么是反射?
Java是一门静态语言,但是又因为使用了各种机制,通常也称Java为准动态语言;其中,反射机制就是为Java提供了一定的动态性。反射机制,在程序运行过程中,能通过反射机制获取类的属性方法等信息。
2.Java类的加载
Java在真正需要使用一个类时才会去加载类,而不是在启动程序时就加载所有类;类的加载是将类的.class 文件加载到内存中,放在Jvm的方法区中,并为每一个类创建一个class对象,class对象放在堆中,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。
3.Class对象
获取Class对象的方法
package com.babyq.study.reflection;
public class Test1 {
public static void main(String[] args) throws ClassNotFoundException {
//方式一 直接由类的全名
Class c1=Class.forName("com.babyq.study.reflection.User");
Class c2=Class.forName("com.babyq.study.reflection.User");
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
A a1=new A();
B b=new B();
A a2=new B();
//方式二 由实例获取
Class c3=a1.getClass();
Class c4=b.getClass();
Class c5=a2.getClass();
System.out.println(c3.hashCode());
System.out.println(c4.hashCode());
System.out.println(c5.hashCode());
//方式三 通过类名获取
Class c7=A.class;
//方式四 一些基本类型可用
Class c8=Integer.TYPE;
}
}
4.获取Class对象
哪些可以获取Class对象?
Class c1=Object.class; //类
Class c2=Comparable.class; //接口 public abstract
Class c3=String[].class; //数组
Class c4=int[][].class; //二维数组
Class c5=Override.class; //注解
Class c6= ElementType.class; //枚举
Class c7=void.class; //void
Class c8=Class.class; //Class
5.由Class对象获取方法和属性
通过class对象能获取类的属性,方法,构造器
public class Test6 {
public static void main(String[] args) throws NoSuchFieldException {
Class c1=User.class; //获取User类的Class对象
System.out.println(c1.getName());
System.out.println(c1.getSimpleName());
System.out.println("=================");
Field[] fields=c1.getFields(); //找到public属性
for (Field field : fields) {
System.out.println(field);
}
Field[] fields1=c1.getDeclaredFields(); //获取全部属性
for (Field field : fields1) {
System.out.println(field);
}
//获取指定属性,传入参数:属性名
Field name=c1.getDeclaredField("name");
System.out.println(name);
//获取类的方法
System.out.println("============================");
Method[] method1=c1.getMethods();
for (Method method : method1) {
System.out.println(method);
}
System.out.println("===================");
Method[] method2=c1.getDeclaredMethods();
for (Method method : method2) {
System.out.println(method);
}
System.out.println("==================");
Constructor[] constructors=c1.getConstructors(); //获取构造器
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
}
}
6.动态创建修改
public class Test7 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class c1 = Class.forName("com.babyq.study.reflection.User");
User user=(User)c1.newInstance(); //本质是调用了无参构造器
System.out.println(user);
//通过构造器创建
Constructor constructor=c1.getDeclaredConstructor(String.class,int.class,int.class);
User user1=(User) constructor.newInstance("aa",10,10);
System.out.println(user1);
//通过反射调用一个方法
Method method=c1.getDeclaredMethod("setName",String.class);
method.invoke(user1,"babyQ");
System.out.println(user1.getName());
User user3=new User();
Field name=c1.getDeclaredField("name");
name.setAccessible(true);
name.set(user3,"baby");
System.out.println(user3.getName());
}
}