详解JAVA 反射机制
什么是反射机制
反射机制是 Java 语言提供的一种能力,它允许本来在编译期无法访问的类的内部信息,在程序运行期可以获取到。使用反射机制,我们可以在程序运行时动态地获取类型信息、构造对象、访问字段和方法等。
反射机制的应用场景
- 设计灵活,可扩展性好。比如很多插件式的框架,允许用户开发自定义的模块,但是这些模块编译时是不确定的,只有在程序运行时才能确定,这时候就需要反射机制。
- 工具类各种框架,例如 Spring,MyBatis 等。这些框架都是基于反射提供核心功能的。
反射机制的基本使用
Java 反射的基本操作都封装在 java.lang.reflect
包中。我们可以通过这个包提供的类来获取类的相关信息。
获取 Class 对象
获取 Class 对象的方法有三种:
- 使用
getClass()
方法:用于获取对象所属的类的 Class 对象。
public class ReflectionDemo {
public static void main(String[] args) {
String str = "Hello, Java";
Class cls = str.getClass();
System.out.println(cls.getName());
}
}
- 使用
.class
方法:用于获取某个类的 Class 对象。
public class ReflectionDemo {
public static void main(String[] args) {
Class cls = String.class;
System.out.println(cls.getName());
}
}
- 使用
Class.forName()
方法:根据类的全限定名获取 Class 对象。
public class ReflectionDemo {
public static void main(String[] args) throws ClassNotFoundException {
Class cls = Class.forName("java.lang.String");
System.out.println(cls.getName());
}
}
创建对象
获取了 Class 对象之后,我们可以通过它来创建对象。一般有两种方式:
- 使用
Class.newInstance()
方法(已过时)。
public class ReflectionDemo {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Class cls = String.class;
String str = (String) cls.newInstance();
System.out.println(str);
}
}
- 使用
Constructor.newInstance()
构造器方法。
public class ReflectionDemo {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class cls = String.class;
Constructor constructor = cls.getConstructor(String.class);
String str = (String) constructor.newInstance("Hello, Java");
System.out.println(str);
}
}
访问属性
- 获取字段。
public class ReflectionDemo {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Person person = new Person();
Class cls = person.getClass();
Field field = cls.getDeclaredField("name");
field.setAccessible(true);
String name = (String) field.get(person);
System.out.println(name);
}
}
class Person {
private String name = "Tom";
}
- 设置字段的值。
public class ReflectionDemo {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Person person = new Person();
Class cls = person.getClass();
Field field = cls.getDeclaredField("name");
field.setAccessible(true);
field.set(person, "Jerry");
String name = (String) field.get(person);
System.out.println(name);
}
}
class Person {
private String name = "Tom";
}
访问方法
- 获取方法。
public class ReflectionDemo {
public static void main(String[] args) throws NoSuchMethodException {
Person person = new Person();
Class cls = person.getClass();
Method method = cls.getDeclaredMethod("sayHello");
method.setAccessible(true);
method.invoke(person);
}
}
class Person {
private void sayHello() {
System.out.println("Hello, Java");
}
}
- 调用方法。
public class ReflectionDemo {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Person person = new Person();
Class cls = person.getClass();
Method method = cls.getDeclaredMethod("getAge");
method.setAccessible(true);
int age = (int) method.invoke(person);
System.out.println(age);
}
}
class Person {
private int age = 18;
private int getAge() {
return age;
}
}
示例1:通过反射获取类的信息
public class ReflectionDemo {
public static void main(String[] args) {
Class cls = String.class;
// 获取类名
System.out.println("类名:" + cls.getName());
// 获取修饰符
int modifiers = cls.getModifiers();
System.out.println("修饰符:" + Modifier.toString(modifiers));
// 获取父类名
String superClassName = cls.getSuperclass().getName();
System.out.println("父类名:" + superClassName);
// 获取接口名
Class[] interfaces = cls.getInterfaces();
for (Class i : interfaces) {
System.out.println("接口名:" + i.getName());
}
}
}
输出结果:
类名:java.lang.String
修饰符:public final
父类名:java.lang.Object
示例2:通过反射动态创建对象
public class ReflectionDemo {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Class cls = String.class;
String str = (String) cls.newInstance();
System.out.println(str);
}
}
输出结果:
Exception in thread "main" java.lang.InstantiationException: java.lang.String
at java.lang.Class.newInstance(Class.java:427)
因为 String 类是不可变类,无法通过反射来修改其中的值,所以会抛出 InstantiationException 异常。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JAVA 反射机制 - Python技术站