反射
反射是在运行时动态地发现和使用类的信息的机制。Java 反射机制提供了程序在运行时拥有访问并操作任何一个对象、变量、方法的能力。
Java 反射最初被设计出来是为了支持类浏览器这样的工具。在此基础上,JavaBean等技术也得以广泛应用。
反射的使用
在Java中,使用反射需要经过如下基本步骤:
1. 获取需要使用的类的Class对象;
2. 根据Class对象获取构造方法、属性、方法等信息;
3. 使用获取到的构造方法、属性、方法等信息进行实例化、访问、操作等。
获取Class对象
在Java中,要获取某个对象的Class对象,可以使用Java反射提供的“类.class”语法或者“实例.getClass()”语法。示例如下:
Class clazz1 = String.class;
Class clazz2 = "hello".getClass();
System.out.println(clazz1);
System.out.println(clazz2);
输出结果:
class java.lang.String
class java.lang.String
获取构造方法
在Java中,可以使用反射获取指定类的构造方法。示例如下:
Class<?> clazz = String.class;
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
输出结果:
public java.lang.String(byte[],java.nio.charset.Charset)
public java.lang.String(byte[],int,int,java.nio.charset.Charset)
public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int) throws java.io.UnsupportedEncodingException
public java.lang.String(byte[],int,int)
public java.lang.String(byte[])
public java.lang.String(java.lang.StringBuilder)
public java.lang.String(byte[],int,int,int)
public java.lang.String(int[],int,int)
public java.lang.String(byte[],int,int,java.nio.charset.CharsetEncoder)
public java.lang.String(char[],int,int)
public java.lang.String(byte[],int,int,java.lang.String,int[])
public java.lang.String()
public java.lang.String(int[],int,int,int)
public java.lang.String(java.lang.String,java.lang.String,java.lang.String)
public java.lang.String(java.lang.String)
public java.lang.String(java.lang.StringBuffer)
public java.lang.String(char[])
public java.lang.String(int[],int,int,int,int[])
public java.lang.String(java.lang.String,int)
获取属性
在Java中,可以使用反射获取指定类的属性。示例如下:
Class<?> clazz = String.class;
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
输出结果:
private final char[] value
private final int offset
private final int count
public static final java.util.Comparator<java.lang.Object> CASE_INSENSITIVE_ORDER
public static final java.lang.String EMPTY
public static final char[] CA
获取方法
在Java中,可以使用反射获取指定类的方法。示例如下:
Class<?> clazz = String.class;
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
输出结果:
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
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 final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public int java.lang.String.compareTo(java.lang.Object)
public int java.lang.String.compareTo(java.lang.String)
public boolean java.lang.String.equals(java.lang.Object)
public java.lang.String java.lang.String.toString()
public native int java.lang.String.hashCode()
public int java.lang.String.length()
public int java.lang.String.indexOf(int)
public int java.lang.String.indexOf(java.lang.String)
public int java.lang.String.indexOf(int,int)
public java.lang.String java.lang.String.substring(int)
public java.lang.String java.lang.String.substring(int,int)
public char[] java.lang.String.toCharArray()
public byte[] java.lang.String.getBytes(java.nio.charset.Charset)
public byte[] java.lang.String.getBytes()
public boolean java.lang.String.endsWith(java.lang.String)
public boolean java.lang.String.equalsIgnoreCase(java.lang.String)
public int java.lang.String.indexOf(java.lang.String,int)
public boolean java.lang.String.isEmpty()
public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String)
public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String)
public java.lang.String java.lang.String.trim()
public boolean java.lang.String.contains(java.lang.CharSequence)
public int java.lang.String.lastIndexOf(int)
public int java.lang.String.lastIndexOf(java.lang.String)
public int java.lang.String.lastIndexOf(int,int)
public java.lang.String java.lang.String.toLowerCase()
public java.lang.String java.lang.String.toUpperCase()
public boolean java.lang.String.matches(java.lang.String)
public java.lang.String[] java.lang.String.split(java.lang.String,int)
public java.lang.String[] java.lang.String.split(java.lang.String)
public java.lang.String java.lang.String.valueOf(java.lang.Object)
public java.lang.String java.lang.String.valueOf(int)
public java.lang.String java.lang.String.valueOf(char[])
public java.lang.String java.lang.String.subSequence(int,int)
public java.util.Locale java.lang.String.getLocale()
public java.lang.String java.lang.String.intern()
示例
示例1:通过反射创建对象并调用方法
public class User {
private String name;
public User(String name) {
this.name = name;
}
public void sayHello() {
System.out.println("Hello, " + name + "!");
}
}
public class Test {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 获取User类的Class对象
Class<?> userClass = User.class;
// 获取User类的构造方法
Constructor<?> constructor = userClass.getConstructor(String.class);
// 调用构造方法创建对象
User user = (User) constructor.newInstance("Tom");
// 获取User类的sayHello方法
Method sayHelloMethod = userClass.getDeclaredMethod("sayHello");
// 调用sayHello方法
sayHelloMethod.invoke(user);
}
}
输出结果:
Hello, Tom!
示例2:通过反射修改私有属性
public class User {
private String name;
public User(String name) {
this.name = name;
}
public void sayHello() {
System.out.println("Hello, " + name + "!");
}
}
public class Test {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
// 创建User对象
User user = new User("Tom");
// 获取User类的Class对象
Class<?> userClass = User.class;
// 获取User类的name属性
Field nameField = userClass.getDeclaredField("name");
// 设置name属性可访问
nameField.setAccessible(true);
// 修改name属性的值
nameField.set(user, "Jerry");
// 调用sayHello方法
user.sayHello();
}
}
输出结果:
Hello, Jerry!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:什么是反射? - Python技术站