获得一个类的类对象有哪些方式?
答:
- 类型.class,例如:
String.class
- 对象.getClass(),例如:
"hello".getClass()
- Class.forName(),例如:
Class.forName("java.lang.String")
如何通过反射创建对象?
答:
- 通过类对象调用
newInstance()
方法,例如:String.class.newInstance()
- 通过类对象的
getConstructor()
或 getDeclaredConstructor()
方法获得构造器(Constructor)对象并调用其 newInstance()
方法创建对象,例如:String.class.getConstructor(String.class).newInstance("Hello");
如何通过反射获取和设置对象私有字段的值?
答:可以通过类对象的 getDeclaredField()
方法字段(Field)对象,然后再通过字段对象的 setAccessible(true)
将其设置为可以访问,接下来就可以通过 get/set 方法来获取/设置字段的值了。下面的代码实现了一个反射的工具类,其中的两个静态方法分别用于获取和设置私有字段的值,字段可以是基本类型也可以是对象类型且支持多级对象操作,例如 ReflectionUtil.get(dog, "owner.car.engine.id");
可以获得 dog 对象的主人的汽车的引擎的 ID 号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List;
public class ReflectionUtil {
private ReflectionUtil() { throw new AssertionError(); }
public static Object getValue(Object target, String fieldName) { Class<?> clazz = target.getClass(); String[] fs = fieldName.split("\\.");
try { for(int i = 0; i < fs.length - 1; i++) { Field f = clazz.getDeclaredField(fs[i]); f.setAccessible(true); target = f.get(target); clazz = target.getClass(); }
Field f = clazz.getDeclaredField(fs[fs.length - 1]); f.setAccessible(true); return f.get(target); } catch (Exception e) { throw new RuntimeException(e); } }
public static void setValue(Object target, String fieldName, Object value) { Class<?> clazz = target.getClass(); String[] fs = fieldName.split("\\."); try { for(int i = 0; i < fs.length - 1; i++) { Field f = clazz.getDeclaredField(fs[i]); f.setAccessible(true); Object val = f.get(target); if(val == null) { Constructor<?> c = f.getType().getDeclaredConstructor(); c.setAccessible(true); val = c.newInstance(); f.set(target, val); } target = val; clazz = target.getClass(); }
Field f = clazz.getDeclaredField(fs[fs.length - 1]); f.setAccessible(true); f.set(target, value); } catch (Exception e) { throw new RuntimeException(e); } }
}
|
如何通过反射调用对象的方法?
答:请看下面的代码:
1 2 3 4 5 6 7 8 9 10
| import java.lang.reflect.Method;
class MethodInvokeTest {
public static void main(String[] args) throws Exception { String str = "hello"; Method m = str.getClass().getMethod("toUpperCase"); System.out.println(m.invoke(str)); } }
|