Java反射:在编译时不确定哪个类被加载,而在程序运行时才加载、探知、使用
反射是指能够在运行时,观察并修改自己运行时(Runtime)行为的特性 Java 反射机制主要提供了以下的一些功能
java.lang.reflect.*
Class 类是 Java 反射机制的起源和入口
Class 类存放类的结构信息
获取 Class 实例的常用方式
// 方法1:对象.getClass()
Class clazz = new Student().getClass();
// 方法2:类.class
Class clazz = Student.class;
// 方法3:Class.forName()
Class clazz = Class.forName("xxx.xxx.Student");
// 方法4:基本数据类型包装类.TYPE
Class<Integer> clazz = Integer.TYPE;
方法 | 说明 |
---|---|
String getName() | 以字符串形式返回该类型的名称 |
String getSimpleName() | 以字符串形式返回该类型的简称 |
Package getPackage() | 获取该类型所在的包 |
Class getSuperclass() | 返回该类型的超类的 Class 实例 |
Class[] getInterfaces() | 返回该类型所实现的全部接口的 Class 实例 |
int getModifiers() | 返回该类型的所有修饰符,由 public、protected、private、final、staic、abstract 等对应的 int 常量组成,返回的整数应使用 Modifier 工具类来解码,才可以判断修饰符的构成 |
Class[] getDeclaredClasses() | 返回该类型中包含的全部内部类的 Class 实例 |
Class getDeclaringClass() | 返回该类型所在的外部类的 Class 实例 |
public class Xz01 {
public static void main(String[] args) throws ClassNotFoundException {
Class<Student> c1 = Student.class;
Class<?> c2 = new Student().getClass();
Class<?> c3 = Class.forName("xuanzi.Student");
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
System.out.println(c1 == c2);
// hashCode 编码以及 内存地址一致表示同一个 Class 对象
System.out.println("获取全类名(包含包路径):" + c1.getName());
System.out.println("获取类名(仅类名称):" + c1.getSimpleName());
System.out.println("获取包名(仅包名):" + c1.getPackage().getName());
System.out.println("获取类加载器:" + c1.getClassLoader());
System.out.println("获取父类路径:" + c1.getSuperclass().getName());
System.out.println("获取类访问修饰符:" + c1.getModifiers());
System.out.println("表示 PUBLIC:" + Modifier.PUBLIC);
}
}
// 1324119927
// 1324119927
// 1324119927
// true
// 获取全类名(包含包路径):xuanzi.Student
// 获取类名(仅类名称):Student
// 获取包名(仅包名):xuanzi
// 获取类加载器:jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
// 获取父类路径:java.lang.Object
// 获取类访问修饰符:1
// 表示 PUBLIC:1
方法 | 说明 |
---|---|
Constructor getConstructor(Class… params) | 返回该类型指定参数列表的 public 构造方法,构造方法的参数列表与 params 所指定的类型列表所匹配 |
Constructor[] getConstructors() | 返回该类型的所有 public 构造方法 |
Constructor getDeclaredConstructor(Class… params) | 返回该类型的指定参数列表的构造方法,访问级别不限 |
Constructor[] getDeclaredConstructors() | 返回该类型的所有构造方法,访问级别不限 |
public class Xz02 {
public static void main(String[] args) throws NoSuchMethodException {
Class<Student> c1 = Student.class;
Constructor<Student> constructor = c1.getConstructor();
Constructor<?>[] constructors = c1.getConstructors();
Constructor<Student> declaredConstructor = c1.getDeclaredConstructor();
Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();
Constructor<?> declaredConstructors1 = c1.getDeclaredConstructor(String.class);
System.out.println(constructor);
System.out.println(Arrays.toString(constructors));
System.out.println(declaredConstructor);
System.out.println(Arrays.toString(declaredConstructors));
System.out.println(declaredConstructors1);
System.out.println("================================");
for (Constructor<?> cc : declaredConstructors) {
int modifier = cc.getModifiers();
String xiu = "";
if ((modifier & Modifier.PUBLIC) == Modifier.PUBLIC) {
xiu = "PUBLIC";
} else if ((modifier & Modifier.PROTECTED) == Modifier.PROTECTED) {
xiu = "PROTECTED";
} else if ((modifier & Modifier.FINAL) == Modifier.FINAL) {
xiu = "FINAL";
} else if ((modifier & Modifier.ABSTRACT) == Modifier.ABSTRACT) {
xiu = "ABSTRACT";
} else if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) {
xiu = "PRIVATE";
} else {
xiu = "未知";
}
System.out.println(xiu);
}
System.out.println("================================");
Class<?>[] parameterTypes = declaredConstructors1.getParameterTypes();
if (parameterTypes.length == 0) {
System.out.println("无参");
} else {
for (int i = parameterTypes.length - 1; i >= 0; i--) {
System.out.println(parameterTypes[i].getSimpleName());
}
}
System.out.println("================================");
}
}
// public xuanzi.Student()
// [public xuanzi.Student(java.lang.String,int,char), public xuanzi.Student()]
// public xuanzi.Student()
// [public xuanzi.Student(java.lang.String,int,char), public xuanzi.Student(), protected xuanzi.Student(java.lang.String), private xuanzi.Student(java.lang.String,int)]
// protected xuanzi.Student(java.lang.String)
// ================================
// PUBLIC
// PUBLIC
// PROTECTED
// PRIVATE
// ================================
// String
// ================================
方法 | 说明 |
---|---|
Field getField(String name) | 返回该类型中指定名称的 public 属性,name 参数用于指定属性名称 |
Field[] getFields() | 返回该类型中所有 public 属性 |
Field getDeclaredField(String name) | 返回该类型中指定名称的属性,与属性的访问级别无关 |
Field[] getDeclaredFields() | 返回该类型中的全部属性,与属性的访问级别无关 |
public class Xz03 {
public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException {
Class<Student> c1 = Student.class;
Field[] fields = c1.getFields();
Field name = c1.getField("name");
Field declaredName = c1.getDeclaredField("name");
Field[] declaredFields = c1.getDeclaredFields();
System.out.println(Arrays.toString(fields));
System.out.println(name);
System.out.println(declaredName);
System.out.println(Arrays.toString(declaredFields));
System.out.println("================================");
for (Field df : declaredFields) {
int modifier = df.getModifiers();
String xiu = "";
if ((modifier & Modifier.PUBLIC) == Modifier.PUBLIC) {
xiu = "PUBLIC";
} else if ((modifier & Modifier.PROTECTED) == Modifier.PROTECTED) {
xiu = "PROTECTED";
} else if ((modifier & Modifier.FINAL) == Modifier.FINAL) {
xiu = "FINAL";
} else if ((modifier & Modifier.ABSTRACT) == Modifier.ABSTRACT) {
xiu = "ABSTRACT";
} else if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) {
xiu = "PRIVATE";
} else {
xiu = "未知";
}
System.out.println(xiu);
}
System.out.println("================================");
for (Field declaredField : declaredFields) {
System.out.print(declaredField.getModifiers() + " - ");
System.out.print(declaredField.getName() + " - ");
System.out.print(declaredField.getType() + " - ");
System.out.println();
}
System.out.println("================================");
}
}
// [public java.lang.String xuanzi.Student.name, public int xuanzi.Student.age]
// public java.lang.String xuanzi.Student.name
// public java.lang.String xuanzi.Student.name
// [public java.lang.String xuanzi.Student.name, public int xuanzi.Student.age, private char xuanzi.Student.gender]
// ================================
// PUBLIC
// PUBLIC
// PRIVATE
// ================================
// 1 - name - class java.lang.String -
// 1 - age - int -
// 2 - gender - char -
// ================================
方法 | 说明 |
---|---|
Method getMethod(String name, Class… params) | 返回该实例中指定的 public 方法,name 参数用于指定方法名称,params 参数指定参数列表 |
Method[] getMethods() | 返回该实例中所有 public 方法 |
Method getDeclaredMethod(String name, Class… params) | 返回该实例中指定的方法,与方法的访问级别无关 |
Method[] getDeclaredMethods() | 返回该实例中的全部方法,与方法的访问级别无关 |
public class Xz04 {
public static void main(String[] args) throws NoSuchMethodException {
Class<Student> c1 = Student.class;
Method[] methods = c1.getMethods();
Method getStudent = c1.getMethod("setName", String.class);
Method[] declaredMethods = c1.getDeclaredMethods();
Method declaredMethod = c1.getDeclaredMethod("getGender");
System.out.println(getStudent);
System.out.println(Arrays.toString(methods));
System.out.println(Arrays.toString(declaredMethods));
System.out.println(declaredMethod);
System.out.println("================================");
for (Method dm : declaredMethods) {
int modifier = dm.getModifiers();
String xiu = "";
if ((modifier & Modifier.PUBLIC) == Modifier.PUBLIC) {
xiu = "PUBLIC";
} else if ((modifier & Modifier.PROTECTED) == Modifier.PROTECTED) {
xiu = "PROTECTED";
} else if ((modifier & Modifier.FINAL) == Modifier.FINAL) {
xiu = "FINAL";
} else if ((modifier & Modifier.ABSTRACT) == Modifier.ABSTRACT) {
xiu = "ABSTRACT";
} else if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) {
xiu = "PRIVATE";
} else {
xiu = "未知";
}
System.out.println(xiu);
}
System.out.println("================================");
for (Method declaredField : declaredMethods) {
System.out.print((declaredField.getModifiers() == Modifier.PUBLIC ? "PUBLIC" : "PRIVATE") + " - ");
System.out.print(declaredField.getName() + " - ");
System.out.print(declaredField.getReturnType().getSimpleName() + " - ");
System.out.print(Arrays.toString(declaredField.getParameterTypes()) + " - ");
System.out.print(Arrays.toString(declaredField.getExceptionTypes()) + " - ");
System.out.println();
}
System.out.println("================================");
}
}
// public void xuanzi.Student.setName(java.lang.String)
// [public java.lang.String xuanzi.Student.getName(), public java.lang.String xuanzi.Student.toString() throws java.lang.IllegalArgumentException,java.lang.ArithmeticException, public void xuanzi.Student.setName(java.lang.String), public int xuanzi.Student.getAge(), public void xuanzi.Student.setAge(int), public void xuanzi.Student.setGender(char), public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]
// [public java.lang.String xuanzi.Student.getName(), public java.lang.String xuanzi.Student.toString() throws java.lang.IllegalArgumentException,java.lang.ArithmeticException, public void xuanzi.Student.setName(java.lang.String), private char xuanzi.Student.getGender(), public int xuanzi.Student.getAge(), public void xuanzi.Student.setAge(int), private java.lang.String xuanzi.Student.show(java.lang.String,int,char), public void xuanzi.Student.setGender(char)]
// private char xuanzi.Student.getGender()
// ================================
// PUBLIC
// PUBLIC
// PUBLIC
// PRIVATE
// PUBLIC
// PUBLIC
// PRIVATE
// PUBLIC
// ================================
// PUBLIC - getName - String - [] - [] -
// PUBLIC - toString - String - [] - [class java.lang.IllegalArgumentException, class java.lang.ArithmeticException] -
// PUBLIC - setName - void - [class java.lang.String] - [] -
// PRIVATE - getGender - char - [] - [] -
// PUBLIC - getAge - int - [] - [] -
// PUBLIC - setAge - void - [int] - [] -
// PRIVATE - show - String - [class java.lang.String, int, char] - [] -
// PUBLIC - setGender - void - [char] - [] -
// ================================
Student student = Student.class.newInstance();
// 通过 class 获取对象
Student student = Student.class.getConstructor().newInstance();
// 通过构造获取对象
public class Xz05 {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Student student = new Student();
// 直接 new 对象
Student student1 = Student.class.newInstance();
// 通过 class 获取对象
Student student2 = Student.class.getConstructor().newInstance();
// 通过构造获取对象
Constructor<Student> studentConstructor = Student.class.getConstructor(String.class, char.class);
studentConstructor.setAccessible(true);
// 通过有参构造获取对象
Student student3 = studentConstructor.newInstance("XuanZi", '男');
Constructor<Student> studentConstructor1 = Student.class.getDeclaredConstructor(String.class, int.class);
studentConstructor1.setAccessible(true);
// 可设置私有构造函数
Student student4 = studentConstructor1.newInstance("XuanZi", 12);
System.out.println(student);
System.out.println(student1);
System.out.println(student2);
System.out.println(student3);
System.out.println(student4);
}
}
// xuanzi.Student{name='null', age=0, gender= }
// xuanzi.Student{name='null', age=0, gender= }
// xuanzi.Student{name='null', age=0, gender= }
// xuanzi.Student{name='XuanZi', age=0, gender=男}
// xuanzi.Student{name='XuanZi', age=12, gender= }
java.lang.reflect.Field
方法 | 说明 |
---|---|
xxx getXxx(Object obj) | xxx 表示8种基本数据类型之一,若 Field 实例表示的是一个静态属性,则 obj 可以设置为 null |
Object get(Object obj) | 以 Object 类型返回 obj 中相关属性的值 |
void setXxx(Object obj, xxx val) | 将 obj 中相关属性的值设置为 val。xxx 为8种基本数据类型之一 |
void set(Object obj, Object val) | 将 obj 中相关属性的值设置为 val |
void setAccessible(boolean flag) | 对相关属性设置访问权限。设置为 true 可以禁止 Java 语言访问检查 |
public class Xz06 {
public static void main(String[] args) throws NoSuchFieldException, InstantiationException, IllegalAccessException {
Class<Student> studentClass = Student.class;
Student student = studentClass.newInstance();
Field name = studentClass.getField("name");
System.out.println(name.get(student));
name.set(student, "玄子");
System.out.println(name.get(student));
}
}
// null
// 玄子
java.lang.reflect.Method
public Object invoke( Object obj, Object... args )
- Object:返回值
- Object obj:执行该方法的对象
- Object… args:执行该方法时传入的参数
public class Xz07 {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {
Class<Student> studentClass = Student.class;
Student student = studentClass.newInstance();
Method name = studentClass.getMethod("setName", String.class);
name.invoke(student, "张三");
System.out.println(student);
}
}
// xuanzi.Student{name='张三', age=0, gender= }