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

举报
肥学 发表于 2022/03/25 23:04:53 2022/03/25
【摘要】 我们继续上一节课的学习下面将进行获取Field constructor Method详解 获取Field 上节课讲了关于Field有几个常用的方法大家还记得吗?不记得没关系自己去前面找。这可不是我懒因...

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

获取Field

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

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

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

//person类里面定义的变量
	private int age;
	private String name;
	public String sex;

  
 
  • 1
  • 2
  • 3
  • 4
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



  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

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);
		
	}

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

这里给一个小技巧在你遇到一个方法时不知道怎么该方法怎么用最简单最直观的方法就是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


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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);
	}

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

特别注意这里不同的是在获取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;
	}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

例:

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)


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

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

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

  
 
  • 1
  • 2
  • 3

创建对象后

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


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

这里新学了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);
	}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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


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,"床上");
	}

}
结果:

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


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

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

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

文章来源: blog.csdn.net,作者:肥学,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/jiahuiandxuehui/article/details/119316198

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。