Java专题 Class反射获取class的三种方法,暴力反射,泛型擦除 总结+案例

反射

java反射:在程序运行过程中,可以对任意一个类型进行任意的操作。例如:加载任意类型、调用类型的任意方法、获取任意的成员变量、构造方法,可以创建该类型的对象。
对于任意一个对象,都能调用这个对象的任意一个方法【不知道要使用什么类型】
如果要获取一个类型的各种内容,首先要获取这个类的字节码对象
解剖这个类型,获取类中的成员,需要使用Class类型中定义的方法
这种【动态】获取信息以及【动态】访问成员的这种方式,称为:反射

	//获取字节码对象的三个方法
	//想要获得和操纵类中的属性和方法就要先获得类的字节码对象
	
	//对象名+ .getClass()
	Sky s1 = new Sky();
	Class<? extends Sky> class1 = s1.getClass();
	
	//类名+ .class
	Class class2 = Sky.class;
	
	//Class.forName("全类名")      (包名.类名)
	Class class3 = Class.forName("zG_review_practice.Sky");
//	全类名可以通过控制台输入,网络获取,通过文件读取
	
	System.out.println(class1);  //获取的是全类名
//	Class类型的实例表示正在运行的java应用程序的类或者接口

反射常用方法

	//常用方法
	Sky sky = class1.newInstance();					//使用该方法新建对象  新建后可以使用对应方法
	
	
	Class<? extends Sky> class4 = sky.getClass();		//获取构造方法
	Constructor constructor = class4.getConstructor(String.class, int.class, double.class);
	Sky sky2 = (Sky)constructor.newInstance("Ocean Bule", 5555, 12.1);
	//getConstructor  按获取的类的构造方法中的类型写顺序,要一致,新建时转为当前类的类型
	
										//私有成员无法访问
	Field field = class2.getField("area");			//获取对应类中的成员变量  参数填变量名
	field.set(sky, "5345.667");						//传入对象和要设置的值
	

暴力反射

通过Class类中:
getDeclaredXxx方法:可以获取类中的所有声明的成员(属性、方法、内部类),私有的成员也可以获取到。

修改该对象的访问权限:
成员变量、构造方法还是成员方法,都是AccessibleObject类型的子类,就具有判断是否可以访问,和设置是否可以访问的方法
isAccessible():判断当前对象是否可以访问
setAccessible(boolean flag):设定当前对象是否可以访问
一旦设定当前对象可以访问,私有的成员也可以被访问,被修改

// 案例
	Class class5 = Sky.class;
	Field field2 = class5.getDeclaredField("area");
	
	System.out.println(field2.isAccessible());            //判断是否可以访问  可不写
	field.setAccessible(true);						 //修改权限  true为可以修改,false不能修改
	
	field2.set(sky2, "5649.999");					//修改完成
	
	
	//获取方法并运行
	Sky sky3 = new Sky();
	Class class6 = Sky.class;
	Method method = class6.getMethod("setColor", String.class);		
	//运行								//写入方法的名字和参数类型   没有参数可以不写或者写null
	method.invoke(sky2, "Ocean");		//写入要调用的对象 和传入的参数  若没有参数则同上处理
	method.getReturnType();				//返回返回值类型	

泛型擦除

一般情况下如果规定了数据的泛型,不符合泛型的数据是不允许加入到存储数据的容器中的
但通过泛型擦除可以做到跳过编译步骤

	List<Integer> list = new ArrayList<Integer>();
	list.add(3452);
//	list.add("fse");					//一般情况下是不能写入的  编译不通过
	
	Class<? extends List> class7 = list.getClass();
	Method method2 = class7.getMethod("add", Object.class);
	method2.invoke(list, "fse");
	method2.invoke(list, '%');
	
	System.out.println(list); 				//会写入上面的值  跳过了编译阶段  类也可以传入
}

以上案例中使用的测试类

class Sky{
	private String color;
	private int height;
	private double area;
	public Sky() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Sky(String color, int height, double area) {
		super();
		this.color = color;
		this.height = height;
		this.area = area;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public int getHeight() {
		return height;
	}
	public void setHeight(int height) {
		this.height = height;
	}
	public double getArea() {
		return area;
	}
	public void setArea(double area) {
		this.area = area;
	}
	@Override
	public String toString() {
		return "Sky [color=" + color + ", height=" + height + ", area=" + area + "]";
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值