测试类:
package org.lam.detector.core.reflect;
public class MyClass {
private String id;
public String name;
public MyClass(){}
public MyClass(String id){
this.id = id;
}
private MyClass(String id, String name){
//....
}
private void privateMethod(){
System.out.println("privateMethod");
}
protected void protectedMethod(){
}
public void publicMethod(){
System.out.println("publicMethod");
}
public void publicMethod(String args){
System.out.println("publicMethod,arguments:" + args);
}
public static void staticMethod(){
System.out.println("staticMethod");
}
}
1、加载类
Class.forName,是个静态方法,用来加载类,方法的返回值是Class<?>,它有两种方式:
1)Class.forName(String name, boolean initialize, ClassLoader loader)
:第一种形式的参数name
表示的是类的全名,包括类的包名;initialize
表示是否初始化类,即是否初始化类的静态成员;loader
表示加载时使用的类加载器。
2)Class.forName(String name):第二种形式设置了参数initialize
的值为true
,loader
的值为当前类的类加载器。
若想了解java的类加载器,点击打开链接
2、类实例
Class<?> clazz = Class.forName("org.lam.detector.core.reflect.MyClass");
Object o = clazz.newInstance();
Constructor<?> c = clazz.getConstructor();
Object o1 = c.newInstance();
如果调用无参构造函数实例对象,使用Class.newInstance()或Constructor.newInstance(),不过推荐使用前者;
如果需要调用传参的构造函数,则:
Constructor<?> c1 = clazz.getConstructor(String.class);
Object o1 = c1.newInstance("222");
其实,若想调用私有的构造函数也是可以的:
Constructor<?> c1 = clazz.getDeclaredConstructor(String.class, String.class);
c1.setAccessible(true);
Object o1 = c1.newInstance("222", "AM");
个人感觉,设计本来就是私有的方法,却可以通过setAccessible(true)修改访问权限,感觉不是太安全。
当然,还有Class.getConstructors(),Class.getDeclaredConstructors()方法,返回所有的构造方法。
3、类的方法
Method ms = clazz.getMethod("publicMethod");
ms.invoke(o);
o为该类的对象,通过Class.getMethod()方法返回类的方法,并通过Method.invoke()调用了方法;
当然,如果想调用传参的方法,这样:
Method ms = clazz.getMethod("publicMethod", String.class);
ms.invoke(o, "I AM arguments");
Class.getMethod()方法只能返回public的方法,如果想取得private或protected的方法,这样:
Method m = clazz.getDeclaredMethod("privateMethod");
m.setAccessible(true);
m.invoke(o1);
跟获取类的构造方法思想相似。还有Class.getMethods(),Class.getDesclaredMethods()获取类的所有方法。
4、类的属性
Field f = clazz.getField("name");
f.set(o, "AM");
System.out.println(f.get(o));
其中f.set(o, "AM")往对象o设置属性name的值,f.get(o)获取对象o属性name的值。
当然Class.getField(String name)只是获取public的属性,若想获取private或protected的属性,这样:
Field f1 = clazz.getDeclaredField("id");
f1.setAccessible(true);
f1.set(o, "123");
System.out.println(f1.get(o1));
获取类的private或protected属性跟获取方法或构造的思路相似,这里不细说了。
获取类的所有属性的方法有Class.getFields()、Class.getDeclaredFields()。