欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java反射的一些使用方法

程序员文章站 2022-07-12 14:30:44
...

注:默认认为反射代码与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());
		}
		
	}
}

 

上一篇: final用法总结

下一篇: git配置文件