上一篇文章初步认识了Java反射机制的基本概念,本文将进一步探究 Java 反射机制的作用。
综述:
获取类之后,可以调用赋值其成员变量,可以调用成员方法,构造方法。对于使用private 修饰的变量、方法和构造方法,需要调用 .setAccessible(true)
直接上代码,一个普通的类,然后待会使用反射机制实例化对象,获取普通常量,普通方法,构造方法,静态方法,静态常量
public class Demo4 {
public Demo4() {
System.out.println("私有化的无参构造函数被实例化");
}
private Demo4(String name) {
System.out.println("public 修饰的有参构造函数被调用:"+name);
}
private String str1="1";
public String str2="2";
String str3="3";
public void method(String name){
System.out.println("调用类的方法,输入参数为:"+name);
}
private void method2(String name){
System.out.println("调用类的方法,输入参数为:"+name);
}
public static String str4="4";
private static void method3(String name,String msg,int a,Integer b){
System.out.println("name="+name+";msg="+msg+";a="+a+";b="+b);
}
}
测试代码
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.Test;
/**
* Java 反射机制
* 实例化类,修改变量值,调用成员方法
* @author wj
*
*/
public class Demo4Test {
@Test
public void test7(){
System.out.println("综述:获取类之后,可以调用赋值其成员变量,可以调用成员方法,构造方法。对于使用private 修饰的变量、方法和构造方法,需要调用 .setAccessible(true)");
}
/**
* 私有化的构造函数被实例化
* public 修饰的无参构造函数 方法有三种 http://blog.csdn.net/bestcxx/article/details/79134315
* Class.forName("demo3.Demo3Class1")
* Demo3Class1.class
* demo31.getClass()
*/
@Test
public void test6(){
Class> obj=Demo4.class;
Constructor> c;//无参构造函数
Constructor> c2;//有参构造函数
try {
//获取无参的构造函数
c = obj.getDeclaredConstructor();
//调用构造函数
c.newInstance();
//---------------------------------------------
//获取有参构造函数
c2=obj.getDeclaredConstructor(String.class);
//允许反射调用 private 的构造函数
c2.setAccessible(true);
//调用构造函数
c2.newInstance("123");
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Java 反射机制 调用 静态方法
* 静态方法本身即代表已被实例化的对象
* method.invoke(method, 传入参数)
*/
@Test
public void test5(){
Class> obj=Demo4.class;
try {
Method method=obj.getDeclaredMethod("method3", String.class,String.class,int.class,Integer.class);
method.setAccessible(true);
System.out.println("method.invoke(method, \"1\",\"2\",3,4)=调用静态方法");
method.invoke(method, "1","2",3,4);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
*反射机制 获取 静态变量
*直接以自己为对象进行取值和赋值
*field.get(field)
*field.set(field, "123")
*/
@Test
public void test4(){
Class> obj=Demo4.class;
try {
Field field=obj.getDeclaredField("str4");
field.setAccessible(true);
System.out.println("field.get(field)=获取静态变量,field 即表示自身和已被实例化的类"+field.get(field));
field.set(field, "123");
System.out.println("field.set(field, \"123\")=给静态变量赋值,field 即表示自身和已被实例化的类"+field.get(field));
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 运用反射机制调用方法
*/
@Test
public void test3(){
Class> obj=Demo4.class;
try {
//获得方法
Method method=obj.getDeclaredMethod("method2", String.class);
//获取一个对象
Object demo4= obj.newInstance();
//允许反射方法调用 private 修饰的方法
method.setAccessible(true);
//反射 调用 方法,并传入参数
method.invoke(demo4, "name2");
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 反射机制 修改 非 public 修饰的变量,比如private、默认、protected
* Field field=obj.getDeclaredField("str1");//如果获取的是 非public 修饰的变量,需要使用 DeclaredField
* field.setAccessible(true);//允许通过反射机制获取和修改 private 修饰的变量
*
*/
@Test
public void test2(){
Class> obj=Demo4.class;
try {
//获得变量,如果获取的是 非public 修饰的变量,需要使用 DeclaredField
Field field=obj.getDeclaredField("str1");
//用反射机制获取一个对象
Object demo4=obj.newInstance();//这里并没有转化为具体的类的对象
//使用反射机制将 获取的成员变量 赋给 demo4 并且赋新值
field.setAccessible(true);//允许通过反射机制获取和修改 private 修饰的变量
//输出 demo4 中 变量 field 的变量值
System.out.println(field.get(demo4));
//将 demo4 中 变量 field 的值修改为 "aaa"
field.set(demo4, "aaa");
//验证值被修改
System.out.println(field.get(demo4));
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 反射机制 修改 public 修饰的变量,将结果赋给指定对象
*/
@Test
public void test1(){
Class> obj=Demo4.class;
try {
Field field=obj.getField("str2");
//用反射机制获取一个对象
Demo4 demo4=(Demo4) obj.newInstance();
System.out.println(demo4.str2);
//使用反射机制将 获取的成员变量 赋给 demo4 并且赋新值
field.set(demo4, "aaa");
//验证值被修改
System.out.println(demo4.str2);
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 反射机制 实例化对象
* 输出成员常量,调用成员方法
*/
@Test
public void test(){
System.out.println("obj.newInstance()=实例化一个 obj类型的对象,可以输出成员常量,调用成员方法");
Class> obj=Demo4.class;
try {
Demo4 demo4=(Demo4) obj.newInstance();
System.out.println(demo4.str2);
demo4.method("Jecket");
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println();
}
}
运行结果
obj.newInstance()=实例化一个 obj类型的对象,可以输出成员常量,调用成员方法
私有化的无参构造函数被实例化
2
调用类的方法,输入参数为:Jecket
私有化的无参构造函数被实例化
2
aaa
私有化的无参构造函数被实例化
1
aaa
私有化的无参构造函数被实例化
调用类的方法,输入参数为:name2
field.get(field)=获取静态变量,field 即表示自身和已被实例化的类4
field.set(field, "123")=给静态变量赋值,field 即表示自身和已被实例化的类123
method.invoke(method, "1","2",3,4)=调用静态方法
name=1;msg=2;a=3;b=4
私有化的无参构造函数被实例化
public 修饰的有参构造函数被调用:123
综述:获取类之后,可以调用赋值其成员变量,可以调用成员方法,构造方法。对于使用private 修饰的变量、方法和构造方法,需要调用 .setAccessible(true)