ZB-035-03反射

反射

  • 根据参数创建一个对象?
  • 根据参数调用一个方法?
  • 根据参数动态获取一个属性?
1
2
3
4
5
6
7
public class WhiteCat extends Cat {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
String className = "java.lang.String";
Class c = Class.forName(className);
Object object = c.getConstructor().newInstance();
}
}

JVM的堆里有一个地方存了,Cat的Class对象(Cat的说明书)

你可以通过这样一个Class.forName(String className) 传递一个类的名字

注意这个类名是 全限定类名
注意这个类名是 全限定类名
注意这个类名是 全限定类名

此时虚拟机根据你的要求加载这个类进来,然后你就能进行一些诡异的操作了

1
2
3
4
// 比如这个
Object object = c.getConstructor().newInstance();

// 不建议用这个 c.newInstance(); jdk9里废弃了 考虑兼容性 不建议使用

这样创建意味着什么?

1
2
3
4
5
6
7
8
9
10
String className = "java.lang.String";
Class c = Class.forName(className);
Object object = c.getConstructor().newInstance();


// 意味着你不再需要这样的调用,
// 而是使用 一个传递的名字,意味着你拥有了无与伦比的灵活性
new String();
new Cat();
new ArrayList();

调用方法,访问成员属性

1
2
3
4
5
6
7
public class WhiteCat extends Cat {
public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException, InvocationTargetException, IllegalAccessException {
Cat cat = new Cat();
cat.getClass().getMethod(args[0]).invoke(cat);
cat.getClass().getField(args[1]).get(cat);
}
}

反射扩展

  • spring-framework里的 ReflectionUtils
    • invokeMethod
  • Method
  • Class
  • Field

练习