本文将通过学习反射工具的部分API并结合具体实例,实现对Java反射机制的初步了解
概述
Java反射机制是指在程序运行过程中,对于任意一个类,都能够获取到该类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
要实际应用Java反射,需要先了解下java.lang.Class类和Java提供反射功能的包java.lang.reflect。
在Java语言中,所有类的对象都是java.lang.Class类的实例,所有类都可以转变为java.lang.Class类型,我们可以通过Class得到一个类的相关信息,如属性和方法等;
java.lang.reflect包下的一些类可以对应接收Class拿到的类的相关信息,如java.lang.reflect.Method接收类中的非构造方法,java.lang.reflect.Field接收类的属性。
实例化Class类对象
想要通过Class类对象拿到类对象的相关信息,首先需要获得Class类对象,可以采用以下方法实现:
1、Class.forName()方法
1
Class? c1 = Class.forName("com.cha.Student");
Class? c1 = Class.forName(“com.cha.Student”);
2、类.class
1
Class? c2 = Student.class;
Class? c2 = Student.class;
3、类对象.getClass()方法
12
Student stu = new Student();Class? c3 = stu.getClass();
Student stu = new Student();
Class? c3 = stu.getClass();
注:Student为自定义的类
反射实际应用
反射实际应用需要java.lang.Class结合java.lang.reflect包下的一些类,下面将以实际代码演示如何通过反射操作类的属性和方法。
应用1:操作类的属性
通过反射取得类的属性,输出属性相关信息并设置属性值
通过Class的getDeclaredField(Stringname)方法和getDeclaredFields()方法可以拿到类属性成员,由java.lang.reflect.Field接收并操作具体属性字段。
API如下:
java.lang.reflect.Field的一些方法可以拿到属性的相关信息,API如下:
代码示例如下:
123456789101112131415161718192021222324252627
try { Class? clazz = Student.class; Field[] fields = clazz.getDeclaredFields(); Object obj = clazz.newInstance(); for(Field field : fields) { System.out.println("属性名称:" + field.getName()); System.out.println("属性类型:" + field.getType().getSimpleName()); boolean flag = field.isAccessible(); System.out.println("属性是否可被外界访问:" + flag); if (!flag) { // 如果不可被访问,则设置为可访问 field.setAccessible(true); } if (field.getType() == String.class) { field.set(obj, "VALUE"); } System.out.println("属性值:" + field.get(obj)); System.out.println("-----------------------------"); }} catch (SecurityException e) { e.printStackTrace();} catch (InstantiationException e) { e.printStackTrace();} catch (IllegalAccessException e) { e.printStackTrace();} catch (IllegalArgumentException e) { e.printStackTrace();}
try {
Class? clazz = Student.class;
Field[] fields = clazz.getDeclaredFields();
Object obj = clazz.newInstance();
for(Field field : fields) {
System.out.println(“属性名称:” + field.getName());
System.out.println(“属性类型:” + field.getType().getSimpleName());
boolean flag = field.isAccessible();
System.out.println(“属性是否可被外界访问:” + flag);
if (!flag) { // 如果不可被访问,则设置为可访问
field.setAccessible(true);
}
if (field.getType() == String.class) {
field.set(obj, “VALUE”);
}
System.out.println(“属性值:” + field.get(obj));
System.out.println(“—————————–”);
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
运行结果:
应用2:操作类的方法
通过反射取得类的方法,输出方法相关信息
通过Class的getDeclaredMethods()方法可以拿到类方法成员。getDeclaredMethods()可以拿到public、protected、default和private修饰的方法,但不包括继承自父类的方法和构造方法。由java.lang.reflect.Method接收并操作具体方法。
java.lang.reflect.Method的一些方法可以拿到类方法的相关信息,API如下:
代码实例如下:
新建Test.java文件,包含各种方法成员,代码如下:
12345678910111213141516171819202122232425262728
public class Test { private String name; public Test() {} public Test(String name) { this.name = name; } public double _public() { // ... return 0.23d; } protected int _protected() { // ... return 10; } private String _private() { // ... return ""; } void _default() { // ... }}
public class Test {
private String name;
public Test() {}
public Test(String name) {
this.name = name;
}
public double _public() {
// …
return 0.23d;
}
protected int _protected() {
// …
return 10;
}
private String _private() {
// …
return “”;
}
void _default() {
// …
}
}
获取Test.java的方法成员:
123456789
Class? clazz = Test.class;Method[] methods = clazz.getDeclaredMethods();for(Method method : methods) { System.out.println("方法名称:" + method.getName()); int modifier = method.getModifiers(); System.out.println("方法控制修饰符:" + Modifier.toString(modifier)); System.out.println("方法返回值类型:" + method.getReturnType()); System.out.println("-------------------------");}
Class? clazz = Test.class;
Method[] methods = clazz.getDeclaredMethods();
for(Method method : methods) {
System.out.println(“方法名称:” + method.getName());
int modifier = method.getModifiers();
System.out.println(“方法控制修饰符:” + Modifier.toString(modifier));
System.out.println(“方法返回值类型:” + method.getReturnType());
System.out.println(“————————-“);
}
getModifiers()获取到的修饰符为int类型,需要借助Modifier.toString()转换为字符串(代码见附2)
运行结果如下:
可以看到运行结果中不包含Test类的构造方法
附1:(导包)
123
import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
附2:Modifier.toString(int mod)实现代码(节选)
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
public static final int PUBLIC = 0x00000001; public static final int PRIVATE = 0x00000002; public static final int PROTECTED = 0x00000004; public static final int STATIC = 0x00000008; public static final int FINAL = 0x00000010; public static final int SYNCHRONIZED = 0x00000020; public static final int VOLATILE = 0x00000040; public static final int TRANSIENT = 0x00000080; public static final int NATIVE = 0x00000100; public static final int INTERFACE = 0x00000200; public static final int ABSTRACT = 0x00000400; public static final int STRICT = 0x00000800; public static String toString(int mod) { StringBuilder sb = new StringBuilder(); int len; if ((mod & PUBLIC) != 0) sb.append("public "); if ((mod & PROTECTED) != 0) sb.append("protected "); if ((mod & PRIVATE) != 0) sb.append("private "); /* Canonical order */ if ((mod & ABSTRACT) != 0) sb.append("abstract "); if ((mod & STATIC) != 0) sb.append("static "); if ((mod & FINAL) != 0) sb.append("final "); if ((mod & TRANSIENT) != 0) sb.append("transient "); if ((mod & VOLATILE) != 0) sb.append("volatile "); if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized "); if ((mod & NATIVE) != 0) sb.append("native "); if ((mod & STRICT) != 0) sb.append("strictfp "); if ((mod & INTERFACE) != 0) sb.append("interface "); if ((len = sb.length()) 0) /* trim trailing space */ return sb.toString().substring(0, len-1); return "";}
public static final int PUBLIC = 0x00000001;
public static final int PRIVATE = 0x00000002;
public static final int PROTECTED = 0x00000004;
public static final int STATIC = 0x00000008;
public static final int FINAL = 0x00000010;
public static final int SYNCHRONIZED = 0x00000020;
public static final int VOLATILE = 0x00000040;
public static final int TRANSIENT = 0x00000080;
public static final int NATIVE = 0x00000100;
public static final int INTERFACE = 0x00000200;
public static final int ABSTRACT = 0x00000400;
public static final int STRICT = 0x00000800;
public static String toString(int mod) {
StringBuilder sb = new StringBuilder();
int len;
if ((mod & PUBLIC) != 0) sb.append("public ");
if ((mod & PROTECTED) != 0) sb.append("protected ");
if ((mod & PRIVATE) != 0) sb.append("private ");
/* Canonical order */
if ((mod & ABSTRACT) != 0) sb.append("abstract ");
if ((mod & STATIC) != 0) sb.append("static ");
if ((mod & FINAL) != 0) sb.append("final ");
if ((mod & TRANSIENT) != 0) sb.append("transient ");
if ((mod & VOLATILE) != 0) sb.append("volatile ");
if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized ");
if ((mod & NATIVE) != 0) sb.append("native ");
if ((mod & STRICT) != 0) sb.append("strictfp ");
if ((mod & INTERFACE) != 0) sb.append("interface ");
if ((len = sb.length()) 0) /* trim trailing space */
return sb.toString().substring(0, len-1);
return "";
}
— END —
原文始发于微信公众号(程序员阿木):【Java】反射机制(应用)