反射(入门)

反射

package entity;

public class User {
	private int id;
	private int age;
	private String name;
	
	
	public User() {
		super();
	}
	
	public User(int id, int age, String name) {
		super();
		this.id = id;
		this.age = age;
		this.name = name;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", age=" + age + ", name=" + name + "]";
	}
	
	

}

package entity;

import java.util.List;
import java.util.Map;

public class TestBean {
	long sum = 0;
	

	public long getSum() {
		return sum;
	}

	public void setSum(long sum) {
		this.sum = sum;
	}

	public void test01(Map<String, User> map, List<User> list){}
	
    public Map<Integer, User>  test02(){
        return null;
    }
	    
	@Override
	public String toString() {
		return "TestBean [sum=" + sum + "]";
	}
	
}

package Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Test;

import entity.TestBean;
import entity.User;

/**
 * 来源参考:https://www.jianshu.com/p/9fab2ddd04cb
 * @author win10
 *
 */
class Reflect_1 {

	/**
	 * 反射入门
	 * 1.获得 Class<类> 对象
	 */
	@Test
	void load() {
		User user = new User(1,2,"张三");
		//1.通过该类的对象直接获得 class 对象
		Class clzz = user.getClass();
		System.out.println("clzz ==> "+clzz);
		//2.通过类 .class 获得
		clzz = User.class;
		System.out.println("clzz ==> "+clzz);
		//3.调用 Class 的静态方法 forName通过全类名来获得
		try {
			String path = "entity.User";
			clzz = Class.forName(path);
			System.out.println("clzz ==> "+clzz);
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 通过反射 api 来获得类的结构信息
	 */
	@Test
	public void getStructInfo() {
		String path = "entity.User";
		try {
			Class clzz = Class.forName(path);
			//获取类的名字
			System.out.println("类全名 :"+clzz.getName());
			System.out.println("类名: "+clzz.getSimpleName());
			
			//获取属性信息
			Field [] fields = clzz.getFields();
			for(Field temp :fields) {
				System.out.println("  属性1:"+temp);
			}
			fields = clzz.getDeclaredFields();	//获取所有的 field
			for(Field temp :fields) {
				System.out.println("  属性2:"+temp);
			}
			
			//获取指定的属性信息
			Field f = clzz.getDeclaredField("name");
			System.out.println("   获取指定属性信息:"+f);
			
			//获取方法信息
			Method [] methods = clzz.getDeclaredMethods();
			for(Method method : methods) {
				System.out.println("   获得方法信息:"+method);
			}
			
			//获取无参指定方法
			Method m1 = clzz.getDeclaredMethod("getName");
			System.out.println("   获取无参指定方法:"+m1);
			
			//获取有参指定方法
			Method m2 = clzz.getDeclaredMethod("setName", String.class);
			System.out.println("   获取无参指定方法:"+m2);
			
			//获得构造器信息
			Constructor [] constructors = clzz.getDeclaredConstructors();
			for(Constructor constructor :constructors) {
				System.out.println("   获得构造器信息:"+constructor);
			}
			//获得无参构造器信息
			Constructor c = clzz.getDeclaredConstructor();
			System.out.println("   获得无参构造器信息:"+c);
			
			//获得有参构造器
			c = clzz.getDeclaredConstructor(int.class,int.class,String.class);
			System.out.println("   有参构造器信息:"+c);
			
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 通过反射 api 动态的操作构造器、方法、属性
	 */
	@Test
	public void operation() {
		String path = "entity.User";
		try {
			Class<User> clzz = (Class<User>)Class.forName(path);
			
			//获得构造器信息
			//通过反射 api 调用构造方法,构造对象
			User u = clzz.getDeclaredConstructor().newInstance();
			u.setName("张三");
			u.setAge(12);
			u.setId(15);
			System.out.println(u);
			
			//通过反射api 调用普通方法
			User user = clzz.getDeclaredConstructor().newInstance();
			Method method = clzz.getDeclaredMethod("setName", String.class);
			method.invoke(user, "李四");
			System.out.println(user);
			
			//通过 反射 api 操作属性
			User user2 = clzz.getDeclaredConstructor().newInstance();
			Field f = clzz.getDeclaredField("name");
			f.setAccessible(true); //解除安全检查,可以通过这个方法使用私有的属性和方法
			f.set(user2, "王五");
			System.out.println(user2.getName());
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 关于反射的效率测试
	 */
	@Test
	public void reflectEfficiency() {
		//普通方法
		TestBean t = new TestBean();
		long startTime1 = System.currentTimeMillis();
		for(int i = 0; i < 1000000000L;i++) {
			t.setSum(i);
		}
		long endTime1 = System.currentTimeMillis();
		System.out.println("和:"+t.getSum());
		System.out.println("普通方法调用 10亿次耗时:"+(endTime1 - startTime1));
		
		//反射调用
		TestBean t2 = new TestBean();
		Class clzz2 = t2.getClass();
		try {
			long startTime2 = System.currentTimeMillis();
			Method m2 = clzz2.getDeclaredMethod("setSum", long.class);
			for(int i = 0; i < 1000000000L;i++) {
				m2.invoke(t2, i);
			}
			long endTime2 = System.currentTimeMillis();
			System.out.println("和:"+t.getSum());
			System.out.println("反射方法调用 10亿次耗时:"+(endTime2 - startTime2));
		}catch (Exception e) {
			e.printStackTrace();
		}
		
		//解除安全检查,反射调用
		TestBean t3 = new TestBean();
		Class clzz3 = t3.getClass();
		try {
			Method m3 = clzz3.getDeclaredMethod("setSum", long.class);
			m3.setAccessible(true);
			long startTime3 = System.currentTimeMillis();
			for(int i = 0; i < 1000000000L;i++) {
				m3.invoke(t3, i);
			}
			long endTime3 = System.currentTimeMillis();
			System.out.println("和:"+t.getSum());
			System.out.println("反射方法调用 10亿次耗时:"+(endTime3 - startTime3));
			
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 反射操作泛型
	 *  ParameterizedType: 表示一种参数化的类型,比如: Clollection<String> (常用)
	 *  GenericArrayType: 表示一种元素类型是参数化类型或者类型变量的数组类型
	 *  TypeVariable: 是各种类型变量的公共父接口
	 *  WildcardType: 代表一种通配符类型的表达式,比如:   ? 、     ? extends Number 、 ? super Integer
	 *  (wildcard 是一个单词,意思就是"通配符")
	 */
	@Test 
	public void operationGenericity() {
		Class clzz = TestBean.class;
		try {
			//获得指定方法的泛型
			Method m = clzz.getMethod("test01", Map.class,List.class);
			//获得方法的所有参数类型
			Type[] t = m.getGenericParameterTypes();
			for(Type paramType:t) {
				System.out.println("#:"+paramType);
				if(paramType instanceof ParameterizedType) {
					
					Type[] genericTypes = ((ParameterizedType)paramType).getActualTypeArguments();
					for( Type genericType :genericTypes) {
						System.out.println("泛型类型: "+genericType);
					}
				}
			}
			
			
			//获得指定方法返回值泛型
			System.out.println("指定方法返回值泛型");
			Method m2 = clzz.getMethod("test02");
			//由于返回值只会有一个,因此不需要数组
			Type returnType = m2.getGenericReturnType();
			if(returnType instanceof ParameterizedType) {
				Type[] genericTypes = ((ParameterizedType)returnType).getActualTypeArguments();
				for(Type genericType:genericTypes) {
					System.out.println("泛型类型:"+genericType);
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值