public class DemoClass {
private String nickName;
public int num = 3;
public int add(int a,int b){
return a + b;
}
public int sub(int a,int b){
return a - b;
}
static {
System.out.println("DemoClass静态代码块");
}
{
System.out.println("DemoClass动态代码块");
}
public DemoClass(){}
public DemoClass(String string){
System.out.println("DemoClass构造方法");
}
public String getNickName() {
return nickName;
}
public void setNickName(String name) {
this.nickName = name;
}
public int getNum() {
return num;
}
private void testMethod(){
System.out.println("静态方法");
}
-
获取类对象
- 直接调用某一个类的class属性(不知道这样说合适不合适)
- 调用某一个对象的getClass方法
- 调用Class类的静态方法forName
public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException { Class<?> classDemo = DemoClass.class;//class demo.DemoClass//不会调用任何方法 Class<?> classNew = new DemoClass().getClass();//class demo.DemoClass 静态代码块和动态代码块还有构造方法都会执行 Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只会调用静态代码块 System.out.println(forName);//class demo.DemoClass System.out.println(classDemo == classNew);//true System.out.println(classNew == forName);//true System.out.println(forName == classDemo);//true } }
-
获取类实例
- 通过newInstance,这种是调用单独无参构造函数,所以如果没有无参构造函数就会异常
- 获取指定的构造函数,再通过指定的构造函数的newInstance创建实例
public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException { Class<?> forName = Class.forName("demo.DemoClass"); try { Object o = forName.newInstance();//这种每次获取的都是同一个对象,class必须有无参构造函数,否则会报错 System.out.println(o);//demo.ReflectDemo@14ae5a } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } try { Constructor<?> constructor = forName.getConstructor(String.class); Object parade = constructor.newInstance("parade"); Object year = constructor.newInstance("year"); System.out.println(parade);//demo.DemoClass@7f31245a System.out.println(year);//demo.DemoClass@6d6f6e28 } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { e.printStackTrace(); } }
-
获取属性
-
getFields->不能获取私有属性
-
getDeclaredFields->可以获取私有属性
public static void main(String[] args) throws ClassNotFoundException { Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只会调用静态代码块 try { Field name = forName.getField("name");//name是私有,则会抛异常 } catch (NoSuchFieldException e) { e.printStackTrace(); } Field[] fields = forName.getFields();//获取所有非私有属性 for (Field field : fields) { System.out.println(field.getName()); } try { Field name = forName.getDeclaredField("name"); System.out.println(name); } catch (NoSuchFieldException e) { e.printStackTrace(); } Field[] declaredFields = forName.getDeclaredFields();//获取所有属性 for (Field declaredField : declaredFields) { System.out.println(declaredField.getName()); } }
-
属性赋值
public static void main(String[] args) throws ClassNotFoundException { Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只会调用静态代码块 try { Field name = forName.getDeclaredField("nickName"); DemoClass o = (DemoClass) forName.newInstance();//通过Class对象得到实例对象 name.setAccessible(true);//将私有属性设置为可访问 name.set(o,"parade");//给私有属性赋值 System.out.println(o.getNickName());//验证赋值成功 Field num = forName.getField("num");//非私有属性赋值 num.setInt(o,5); System.out.println(o.getNum());//验证赋值成功 Object o1 = num.get(o);//或者继续通过反射获取属性值 System.out.println(o1); } catch (NoSuchFieldException | IllegalAccessException | InstantiationException e) { e.printStackTrace(); } }
-
-
获取方法->类似获取属性
-
getMethod->不能获取私有方法
-
getDeclaredMethods
Method[] methods = forName.getMethods();//会得到所有非private方法,包括父类的方法 for (Method method : methods) { System.out.println(method.getName()); } Method[] declaredMethods = forName.getDeclaredMethods();//获取本类的所有方法,不包括父类 for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod.getName()); }
-
调用方法
public static void main(String[] args) throws ClassNotFoundException { Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只会调用静态代码块 try { DemoClass demoClass = (DemoClass) forName.newInstance();//调用方法前先要获得一个实例对象才能调用实例对象的方法 Method setNickName = forName.getMethod("setNickName", String.class); Method getNickName = forName.getMethod("getNickName"); setNickName.invoke(demoClass, "Are you ok"); System.out.println(getNickName.invoke(demoClass)); Method testMethod = forName.getDeclaredMethod("testMethod"); testMethod.setAccessible(true);//调用私有方法同样要设置可访问 testMethod.invoke(demoClass); } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } }
-