步步UP3️⃣——反射之class对象功能详解

我们继续上一节课的学习下面将进行获取Field constructor Method详解

获取Field

上节课讲了关于Field有几个常用的方法大家还记得吗?不记得没关系自己去前面找。这可不是我懒因为自己在寻找过程中记东西会更有效一点点,这也是为啥我分开写没有全部写在一篇的道理。

我们首先说Field [ ] getField()方法

该方法只能获取public的成员变量至于能不能获取处public以外类型的变量你可以试试,路都是自己走出来的嘛。来看下面例子:

//person类里面定义的变量
	private int age;
	private String name;
	public String sex;
package reflect;
import java.lang.reflect.Field;
import java_practice.Person;

public class ReflectDemol {
	public static void main(String[] args) throws ClassNotFoundException {
		Class cs=Person.class;
		Field[] fileds=cs.getFields();
		for(Field f: fileds) {
			System.out.println(f);
		}
	}

}
结果:
public java.lang.String java_practice.Person.sex


Field [ ] getField(String name)方法

可以看出该方法和上一个方法就只是差了个参数,作用就简洁明了了。上一个是获取所有的public类型的成员变量这个当然是获取某一个了。当然我们获取变量的目的大家应该很清楚无非得到数据传输数据下面我们实际操作一下。


public class ReflectDemol {
	public static void main(String[] args) throws Exception {
		Class cs=Person.class;
		Person p=new Person();
		Field field2=cs.getField("sex");
		Object value2=field2.get(p);//获取sex变量的值
		System.out.println(value2);//这个时候sex只是一个空值
		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~");
		
		
		field2.set(p, "男");//设置sex的值
		Object value3=field2.get(p);
		System.out.println(value3);
		
	}

}

这里给一个小技巧在你遇到一个方法时不知道怎么该方法怎么用最简单最直观的方法就是Ctrl+鼠标左键点解该方法直接看源码。

Field [ ] getDeclareFields()方法

这个方法跟上面比较多了一个Declare多个东西就像是加了buff它就可以获取所有变量了不在考虑是什么修饰符。无论是private还是protected——都拿来吧你。下面看操作:

public class ReflectDemol {
	public static void main(String[] args) throws Exception {
		Class cs=Person.class;
		Person p=new Person();
		Field[] fields=cs.getDeclaredFields();
		for(Field f: fields) {
			System.out.println(f);
		}
	}

}

结果:
private int java_practice.Person.age
private java.lang.String java_practice.Person.name
public java.lang.String java_practice.Person.sex

Field [ ] getDeclareFields(String name)方法

具体操作和上面的getField类似可以用它来得到和修改数据:

public class ReflectDemol {
	public static void main(String[] args) throws Exception {
		Class cs=Person.class;
		Person p=new Person();
		Field name=cs.getDeclaredField("name");
		name.setAccessible(true);//暴力反射
		Object value=name.get(p);
		System.out.println(value);
		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
		name.set(p, "肥学");
		Object value2=name.get(p);
		System.out.println(value2);
	}

}

特别注意这里不同的是在获取private修饰的变量时要加一句setAccessible(true)这个是关于忽略访问权限修饰符的安全检查。也称暴力反射。所以学到这里大家要知道在Java里面没有什么绝对的私有。

Constructor获取

Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)方法

为了让大家充分的调动,我这里就写这一个例子其他的大家自己写写,不会的在私聊我。
获取constructor肯定要现有构造方法了呀这里我随便建了两个接着上面的Person.java

public Person(int age) {
		this.age=age;
	}
	private Person(String name) {
		this.name=name;
	}

例:

public class ReflectDemol {
	public static void main(String[] args) throws Exception {
		Class cs=Person.class;
		Constructor con=cs.getDeclaredConstructor(int.class);
		System.out.println(con);
		Constructor con2=cs.getDeclaredConstructor(String.class);
		System.out.println(con2);
	}

}
结果:
public java_practice.Person(int)
private java_practice.Person(java.lang.String)

我们使用constructor当然要创建对象啊,构造方法不创建对象那不是白瞎了。
下面我又在person类里面重写了toString方法

public String toString() {
		return name+ " "+ sex + " "+ age;
	}

创建对象后

public class ReflectDemol {
	public static void main(String[] args) throws Exception {
		Class cs=Person.class;
		Constructor con=cs.getDeclaredConstructor(int.class);
		System.out.println(con);
		Constructor con2=cs.getDeclaredConstructor(String.class);
		con2.setAccessible(true);
		Object person=con2.newInstance("肥学");//创建对象
		System.out.println(person.toString());
		
	}

}

结果:
public java_practice.Person(int)
肥学 null 0

这里新学了newInstance()它和创建对象的new还是有很多不同的但都是创建对象。好了constructor获取就介绍到这里

Method获取

Method getMethod(String name, Class<?>... parameterTypes)方法

下面我们先在person类里面创建两个方法:

public void sleep() {
		System.out.println("我睡觉了");
	}
	public void sleep(String place) {
		System.out.println("我睡觉了在"+place);
	}

还记的这是方法的重写还是重载吗?评论区告诉我一下。嘻嘻嘻答对了有奖励哦
下面我们就有参和无参进行演示:


public class ReflectDemol {
	public static void main(String[] args) throws Exception {
		Class cs=Person.class;
		Person p=new Person();
		Method sleep1=cs.getMethod("sleep");
		//执行
		sleep1.invoke(p);
		
		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		Method sleep2=cs.getMethod("sleep",String.class);
		//执行
		sleep2.invoke(p,"床上");
	}

}
结果:

我睡觉了
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我睡觉了在床上

这里用到了函数invoke()由例子我们就可以看出当有参时需要对invoke()函数里的args进行参数传递。当然这里也可以用Method[] getDeclaredMethods()来无视修饰符进行操作但是别忘了setAccessible(true),我就不一 一操作了。

这篇我们就学到这里,大家有空也可以去看看python的有趣编程:链接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥学

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值