通过java语言中的反射机制可以操作字节码文件
在 java.lang.reflect包下面
获取Class的三种方式
Class
Class c1 = Class.forName("java.lang.String");
Class.forName是一个静态方法
方法的参数是一个字符串,是类的全限定类名
java中任何一个对象都有一个方法,叫做getClass()
在Object中
String s = "abc";
Class x = s.getClass();
x 代表String.class字节码文件,x代表String类型
字节码文件装载到JVM中,只装载一份
java语言中的任何一种类型,包括基本类类型(int等),都有.class属性
Class x = String.class;
Class f = int.claass;
通过Class来实例化对象:
Class的示例有一个方法,叫newInstance()
(jdk9以后取消了)
newInstance会调用类的无参构造方法,完成对象的实例化。 要保证无参构造方法存在。
把资源文件放到src根目录(类路径)下,
利用类加载器拿到绝对路径,项目移植了路径也不会变
资源绑定器
反射Field
java.lang.Class
通过反射机制访问一个java对象的属性
为了访问私有的private属性,
要设置 setAccessible(true)
反射机制的缺点:打破封装,可能会给不法分子留下机会
public static void main(String[] args) throws Exception {
Person p = new Person();
Class myClass = Person.class;
Field fields = myClass.getDeclaredField("name");
fields.setAccessible(true);
fields.set(p, "yunthin");
System.out.println(fields.get(p));
}
反射Method
可变长参数:
语法:类型… (一定是三个点)
注意:可变长参数在参数列表中必须在最后一个位置上,而且可变长度参数只能有一个
其实是一个数组
所以也可以传一个数组
public static void main(String[] args) throws Exception {
Person p = new Person();
Class myClass = Person.class;
Method myMethod = myClass.getMethod("eat");
myMethod.invoke(p);
Method myMethod2 = myClass.getMethod("eat",String.class);
myMethod2.invoke(p,"food");
Method[] methods = myClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
}