`

Java反射的一些使用方法

阅读更多

注:默认认为反射代码与Worker类不在同一个包下,下面的“使用条件”才是正确的。

 

下面以Worker类来讲解Java反射的三种用途(创建实例,调用方法,访问属性):

Worker类如下:

 

class Worker{
	/*两个public构造方法*/
	public Worker(){
		count++;
	}
	public Worker(String name){
		super();
		this.name = name;
	}
	
	/*两个private构造方法*/
	private Worker(String name,int age){
		super();
		this.name = name;
		this.age = age;
	}
	private Worker(int age){
		super();
		this.age = age;
	}
	
	/*两个private属性*/
	private String name;
	private int age;
	
	/*一个public属性*/
	public String parents;
	
	/*一个private static属性*/
	private static int count;
	
	/*一个 public static属性*/
	public static String address;
	
	/*两个public方法*/
	public String getName(){
		return name;
	}
	public void setName(String name){
		this.name = name;
	}
	
	/*两个private方法*/
	private int getAge(){
		return age;
	}
	private void setAge(int age){
		this.age = age;
	}
	
	/*两个public static方法*/
	public static void printAddress(String address){
		System.out.println("printAddress==="+address);
	}
	public static void printAddress(){
		System.out.println("printAddress===default");
	}
	
	/*两个private static方法*/
	private static void printlnCount(int count){
		System.out.println("printCount==="+count);
	}
	private static void printlnCount(){
		System.out.println("printCount===000");
	}
	
	@Override
	public String toString(){
		return "这是一个Worker实例:name="+name+",age="+age;
	}
}

 在使用反射时,第一步要获取,被反射类的Class对象。获取Class对象有3中方法,如下:

 

 

package test;

public class ReflectTest {
	public static void main(String[] args) throws Exception{
		//方法1,使用"包名.类名.class"形式获取Class对象
		Class c1 = Worker.class;
		System.out.println("c1==="+c1);
		
		//方法2,使用"对象名.getClass()"形式获取Class对象
		Worker w = new Worker();
		Class c2 = w.getClass();
		System.out.println("c2==="+c2);
		
		//方法3,使用"Class.forName("包名.类名")"形式获取Class对象
		Class c3 = Class.forName("test.Worker");
		System.out.println("c3==="+c3);
	}
}

 第一,创建实例

 

 

package test;

import java.lang.reflect.Constructor;

public class ReflectTest {
	public static void main(String[] args) throws Exception{
		//提前获取Class对象
		Class c = Class.forName("test.Worker");
		
		//创建实例
		
		//方法1,使用"Class对象名.newInstance()"创建实例
		//使用条件:该方法要求Worker类必须有public类型且无参的构造方法
		Worker w1 = (Worker)c.newInstance();
		System.out.println("w1==="+w1);
		
		//方法2,使用getConstructor创建实例
		//方法2.1,公有、无参构造方法
		//使用条件:该方法要求Worker类有一个public类型且无参的构造方法
		Constructor con21 = c.getConstructor();//只能获取public类型的无参构造方法
		Worker w21 = (Worker)con21.newInstance();
		System.out.println("w21==="+w21);
		
		//方法2.2,公有、有参构造方法
		//使用条件:该方法要求Worker的构造方法是公有的
		Constructor con22 = c.getConstructor(String.class);//根据构造方法的参数类型和顺序,传入对应的Class对象
		Worker w22 = (Worker)con22.newInstance("李彦宏");//根据构造方法的参数类型和顺序,传入对应的参数
		System.out.println("w22==="+w22);
		
		//方法3,使用getDeclaredConstructor创建实例
		//方法3.1,无参构造方法
		Constructor con31 = c.getDeclaredConstructor();//无论是private还是public类型的无参构造方法,都可以获取
		con31.setAccessible(true);//关键,如果无参构造方法是private类型的,这句必须加
		Worker w31 = (Worker)con31.newInstance();
		System.out.println("w31==="+w31);
		
		//方法3.2,有参构造方法
		Constructor con32 = c.getDeclaredConstructor(String.class,int.class);//根据构造方法的参数类型和顺序,传入对应的Class对象
		con32.setAccessible(true);//关键,如果无参构造方法是private类型的,这句必须加
		Worker w32 = (Worker)con32.newInstance("周星驰",40);//根据构造方法的参数类型和顺序,传入对应参数
		System.out.println("w32==="+w32);
	}
}

 第二,调用方法

 

 

package test;

import java.lang.reflect.Method;

public class ReflectTest {
	public static void main(String[] args) throws Exception{
		//提前获取Class对象
		Class c = Class.forName("test.Worker");
		
		//调用方法
		
		//方法1,调用静态方法
		//使用条件:使用之前需要先获取该类的Class对象
		
		//方法1.1,调用公有、无参构造方法
		//使用条件:该方法必须是public static和无参的
		Method m11 = c.getMethod("printAddress");
		m11.invoke(c);
		
		//方法1.2,调用公有、有参构造方法
		//使用条件:该方法必须是public static和有参的
		Method m12 = c.getMethod("printAddress",String.class);//根据参数名、参数类型和顺序,填入正确的参数名、参数的Class对象
		m12.invoke(c, "北京");//传入该类的Class对象,和方法对应的参数
		
		//方法1.3,调用私有、有参构造方法
		//使用条件:该方法无论是public还是private类型都可以使用
		Method m13 = c.getDeclaredMethod("printlnCount", int.class);
		m13.setAccessible(true);//关键,如果该方法是private类型的,则这句必须加
		m13.invoke(c, 100);
		
		//方法2,调用成员方法
		//使用条件:使用之前必须先创建实例
		Worker w = (Worker)c.newInstance();
		
		//方法2.1,调用公有、无参成员方法
		//使用条件:该方法必须是public类型且无参的方法
		Method m21 = c.getMethod("getName");
		System.out.println("getName==="+m21.invoke(w));
		
		//方法2.2,调用公有、有参成员方法
		//使用条件:该方法必须是public类型且有参的方法
		Method m22 = c.getMethod("setName", String.class);
		m22.invoke(w, "李开复");
		
		//方法2.3,调用私有、有参成员方法
		//使用条件:该方法可以是public,也可以是private类型
		Method m23 = c.getDeclaredMethod("setAge", int.class);
		m23.setAccessible(true);//关键,如果该方法是private类型方法,则必须加上
		m23.invoke(w,20);
		
		//另:遍历所有public方法(包括静态方法和成员方法,--也包括--父类的方法)
		Method [] ms1 = c.getMethods();
		for(Method m:ms1){
			System.out.println(m.getName());
		}
		
		//遍历所有方法(包括静态方法和成员方法,--不包括--父类的方法)
		Method [] ms2 = c.getDeclaredMethods();
		for(Method m:ms2){
			System.out.println(m.getName());
		}
	}
}

 第三访问属性

 

 

 

package test;

import java.lang.reflect.Field;

public class ReflectTest {
	public static void main(String[] args) throws Exception{
		//提前获取Class对象
		Class c = Class.forName("test.Worker");
		
		//访问属性
		
		//方法1,访问静态属性
		//使用条件:使用之前需要先获取该类的Class对象
		
		//方法1.1,访问public static属性
		//使用条件:该属性必须是public static
		Field f11 = c.getField("address");
		f11.set(c, "天津");
		System.out.println("address==="+f11.get(c));
		
		//方法1.2,访问private static属性
		//使用条件:该属性必须是static类型,可以是public类型,也可以是private类型
		Field f12 = c.getDeclaredField("count");
		f12.setAccessible(true);//关键,如果该属性是private类型,则该句必须加上
		f12.set(c, 100);
		System.out.println("count==="+f12.get(c));
		
		//2.访问成员属性
		//使用条件:使用之前需要先获取该类的实例
		Worker w = new Worker("凤姐");
		System.out.println("w.getName()==="+w.getName());
		
		//方法2.1,访问public成员属性
		//使用方法:该属性必须是public成员属性
		Field f21 = c.getField("parents");
		f21.set(w, "如花");
		System.out.println("w.parents==="+w.parents);
		
		//方法2.2,访问private成员属性
		//使用方法:该属性可以是public类型,也可以是private类型
		Field f22 = c.getDeclaredField("name");
		f22.setAccessible(true);//关键,如果是private类型属性,则该句必须加上
		f22.set(w, "芙蓉姐姐");
		System.out.println("w.getName()==="+w.getName());
		
		
		//另:遍历所有的public属性
		Field [] fs1 = c.getFields();
		for(Field f:fs1){
			System.out.println("f==="+f.getName());
		}
		
		//遍历所有的属性
		Field [] fs2 = c.getDeclaredFields();
		for(Field f:fs2){
			System.out.println("f==="+f.getName());
		}
		
	}
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics