DAY11.1 Java核心基础
反射
重点和难点,应用面很广
大部分库和框架都需要用到反射机制,它是动态语言的关键,但是概念抽象不好理解
反射:通过实例化类映射到类,从而获取类的信息
概括说就是:常规情况是通过类来创建实例化对象,而反射就是将这个过程反转,通过实例化对象获取类的信息
Class类(反射 API 的入口)
Class类是反射的基础
Class类:是专门用来描述其它类的类
对每一种对象,JVM 都会实例化一个 java.lang.Class 的实例,java.lang.Class 为我们提供了在运行时访问对象的属性和类型信息的能力。
Class 还提供了创建新的类和对象的能力。最重要的是,Class 是调用其他反射 API 的入口,我们必须先获得一个 Class 实例才可以进行接下来的操作。
创建Class对象的三种方式
-
forName():Class的静态方法forName()方法
-
.class:通过实体类的.class直接取得
-
getClass():通过创建实体类的getClass()方法获取
java">public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {File file1 = new File("H:\\Java代码库\\DeepSeek_Tesat\\src\\main\\java\\com\\deepSeek\\shuwu\\Day10\\test3.txt");Class class1 = Class.forName("com.deepSeek.shuwu.Day10.User");Class<User> class2 = User.class;User user = new User("deepSeek", 18);Class<? extends User> class3 = user.getClass();System.out.println(class1);System.out.println(class2);System.out.println(class3);
}
那么这三个class对象是否为同一个呢?
我们来验证一下
java">System.out.println(class1 == class2);
System.out.println(class3 == class2);
System.out.println(class2 == class3);
可以看见这个为ture,哈哈,原来这个是一样的对象
为什么呢?
这时候就要提到大名鼎鼎的JVM了
JVM的类加载机制:程序中使用到某个类的时候,需要通过类加载器加载静态文件到JVM中,从而创建对象
每个类只加载一次,JVM每个类只有一个
所以用来描述它的class必然只有一个,所以无论通过那种方式获取class对象,都是同一个对象
Class是整个反射机制的源头
跟反射相关的操作大部分都是基于对象的操作,获取目标类的信息都是通过调用class的相关方法来完成的
类的信息:成员变量、成员方法、构造函数、继承的父类、实现的接口等…
Class的常用方法
方法 | 描述 |
---|---|
public native boolean isInterface() | 判断该类是否为接口 |
public native boolean isArray() | 判断该类是否为数组 |
public boolean isAnnotation() | 判断该类是否为注解 |
public String getName() | 获取该类的全类名 |
public ClassLoader getClassLoader() | 获取类加载器 |
public native Class getSuperclass() | 获取该类的直接父类 |
public Package getPackage() | 获取该类所在的包 |
public String getPackageName() | 获取该类所在包的名称 |
public Class[] getInterfaces() | 获取该类的全部接口 |
public native int getModifiers() | 获取该类的访问权限修饰符 |
public Field[] getFields() | 获取该类的全部公有成员变量,包括继承自父类的和自定义的 |
public Field[] getDeclaredFields() | 获取该类的自定义成员变量 |
public Field getField(String name) | 通过名称获取该类的公有成员变量,包括继承自父类的和自定义的 |
public Field getDeclaredField(String name) | 通过名称获取该类的自定义成员变量 |
public Method[] getMethods() | 获取该类的全部公有方法,包括继承自父类的和自定义的 |
public Method[] getDeclaredMethods() | 获取该类的自定义方法 |
public Method getMethod(String name,Class… parameterTypes) | 通过名称和参数信息获取该类的公有方法,包括继承自父类的和自定义的 |
pyblic Method getDeclaredMethod(String name,Class… parameterTypes) | 通过名称和参数信息获取该类的自定义方法 |
public Constructor[] getConstructors() | 获取该类的公有构造函数 |
public Constructor[] getDeclaredConstructors() | 获取该类的全部构造函数 |
public Constructor getConstructor(Class… parameterTypes) | 通过参数信息获取该类的公有构造函数 |
public Consrructor getDeclaredConstructor(Class… parameterTypes) | 通过参数信息获取该类的构造函数 |
java中数据类型分为两种:基本类型和引用类型
引用类型一定是对象,而对象一定有Class类
获取类的接口 getInterfaces()
测试User类:
java">public class User implements Serializable{public String name;private int age;public User(String name, int age) {this.name = name;this.age = age;}public String test(String name){return name;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}
main:
java">public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException {Class class1 = Class.forName("com.deepSeek.shuwu.Day10.User");System.out.println(class1.isInterface());Class[] interfaces = class1.getInterfaces();for (Class anInterface : interfaces) {System.out.println(anInterface);}}
输出:
因为获取类可以实现多个接口,所以用数组返回
获取父类 getSuperclass()
public class User extends List {}
java">Class class1 = Class.forName("com.deepSeek.shuwu.Day10.User");
System.out.println(class1.getSuperclass());
获取构造方法
Class 提供了 4 个方法获取构造函数
public Constructor[] getConstructors() :获取所有公有(public)的构造器
public Constructor[] getDeclaredConstructors() :获取所有构造器
public Constructor getConstructor(Class… parameterTypes) :获取单个公有(public)的构造器
public Consrructor getDeclaredConstructor(Class… parameterTypes) :获取单个构造器
反射机制专门提供的一个类 Constructor,专门用来描述类的构造器
Class 专门用来描述类的信息,Constructor 专门用来描述类的构造器
java">public class User {private String name;private int age;public User(String name, int age) {this.name = name;this.age = age;}public User() {}private User(String name){this.name = name;}protected User(int age){this.age = age;}
}
java">public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException {Class class1 = Class.forName("com.deepSeek.shuwu.Day10.User");Constructor[] constructors = class1.getConstructors();for (Constructor constructor : constructors) {System.out.println(constructor);} public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException {Class class1 = Class.forName("com.deepSeek.shuwu.Day10.User");System.out.println("获取所有公有的构造器");Constructor[] constructors = class1.getConstructors();for (Constructor constructor : constructors) {System.out.println(constructor);}System.out.println("根据参数类型获取单个公有构造器");System.out.println(class1.getConstructor(String.class, int.class));System.out.println("获取所有构造器");for (Constructor constructor : class1.getDeclaredConstructors()) {System.out.println(constructor);}System.out.println("根据参数类型获取单个构造器");System.out.println(class1.getDeclaredConstructor(String.class, int.class));}
}
可以看见公有的有两个,所有的有四个,有Declared则就是所有的