栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java反射机制的基本使用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java反射机制的基本使用

目录

一、什么是反射

二、java.lang.Class类类

三、反射如何实例化

四、反射动态方法的调用

五、反射如何读写属性

六、反射如何访问属性修饰符


一、什么是反射

反射就是Java语言中的一种机制,

通过这种机制可以动态的实例化对象、读写属性、调用方法。


二、java.lang.Class类类

我们需要使用Java反射机制的话就必须要先获得你想操作的类的java.lang.Class对象;

然后接下来我们就来一起了解一下类类的几种获取方式吧:

我们先放上学习案例需要的一个实体类:Student

package com.leaf.reflect;


public class Student {
	private String sid;

	private String sname;

	public Integer age;
	
	static{
		System.out.println("加载进jvm中!");
	}

	public Student() {
		super();
		System.out.println("调用无参构造方法创建了一个学生对象");
	}

	public Student(String sid) {
		super();
		this.sid = sid;
		System.out.println("调用带一个参数的构造方法创建了一个学生对象");
	}

	public Student(String sid, String sname) {
		super();
		this.sid = sid;
		this.sname = sname;
		System.out.println("调用带二个参数的构造方法创建了一个学生对象");
	}

	@SuppressWarnings("unused")
	private Student(Integer age) {
		System.out.println("调用Student类私有的构造方法创建一个学生对象");
		this.age = age;
	}

	public String getSid() {
		return sid;
	}

	public void setSid(String sid) {
		this.sid = sid;
	}

	public String getSname() {
		return sname;
	}

	public void setSname(String sname) {
		this.sname = sname;
	}

	public void hello() {
		System.out.println("你好!我是" + this.sname);
	}

	public void hello(String name) {
		System.out.println(name + "你好!我是" + this.sname);
	}

	@SuppressWarnings("unused")
	private Integer add(Integer a, Integer b) {
		return new Integer(a.intValue() + b.intValue());
	}
}
获取Class对象的三种方式:

2.1 类.class

//1、类.class
Class cl1 = Student.class;

2.2  类实例.getClass()

//2、类实例.getClass()
Student stu = new Student();
Class cl2 = stu.getClass();

2.3 Class.forName("类的全路径名"); 

//3、Class.forName("类的全路径名");
Class cl3 = Class.forName("com.leaf.reflect.Student"); 


三、反射如何实例化

使用Java反射机制的第一步获取Class的三种方式我们都了解过了,

接下来我们就来了解一下如何用反射来实例化一个对象吧:

我们以前一般实例化一个对象是这样做的:

Student stu = new Student();

而接下来我们就看看用反射又如何来实例化:

3.1 第一步还是获取Class类:

//获取类类
Class cl1 = stu1.getClass();

3.2 无参的 共有的构造函数:

1、无参数 共有的构造方法
Student stu = cl1.newInstance();

 3.3 有参数 共有的构造方法:

2、有参数 共有的构造方法
//拿到构造器对象 三个点代表可以传n个参数--->拿到一个参数为String的构造器对象
Constructor c1 = cl1.getConstructor(String.class);
Student stu5 = c1.newInstance("s001");

3.4 拿到有多个参数 共有的构造方法:

3、拿到有多个参数 共有的构造方法
Constructor c2 = cl1.getConstructor(String.class,String.class);
Student stu6 = c2.newInstance("s002","颠婆"); 

3.5 私有的构造方法:

4、私有的构造方法
//getConstructor只能获取共有的构造方法,要获取私有的构造器getDeclaredConstructor
Constructor c3 = cl1.getDeclaredConstructor(Integer.class);
//打开访问权限
c3.setAccessible(true);
Student stu = c3.newInstance(19); 

我们可以看到调用的实体类的方法运行结果:

 最后总结一下反射机制实例化对象的步骤以及注意点:

1)拿到Class类;

2)Class类点newInstance();--->没有参数的实例化

3)有参数的实例化还要拿到构造器对象: Class类点getConstructor("参数的类型.class");

再用构造器对象点newInstance();

4)如果是私有的构造方法还就需要拿到私有的构造器对象:

Class类点getDeclaredConstructor("参数的类型.class");

然后再打开访问权限:构造器对象点setAccessible(true);

最后再用构造器对象点newInstance();


 四、反射动态方法的调用

如何使用反射机制动态调用方法呢?一起来看看吧:

4.1 第一步还是先拿到类类:类点Class

1、拿到类类
Class cl1 = Student.class; 

4.2 拿到方法对象:getMethod("方法名");

2、拿到方法对象
//name:方法名    parameterTypes:方法对应的参数类型
Method m1 = cl1.getMethod("hello");

4.3 调用对应的方法:invoke(类实例, "参数");

3、调用对应的方法
//第一个参数:类实例    第二个参数:方法调用时的实际参数
//m1.invoke方法调用的返回值就是方法对象本身hello方法的返回值
Object invoke = m1.invoke(cl1.newInstance());

我们打印测试一下:

 由于方法是void无返回,所以值为null,

但是根据文章开头提供的案例类Student可以发现方法已经成功调用~ 

还有有参以及私有方法的调用,步骤基本一致,这里就直接放上代码了:

Method m2 = cl1.getMethod("hello", String.class);
Object invoke2 = m2.invoke(cl1.newInstance(), "邓正威");
System.out.println(invoke2);

运行结果:

 

//拿到私有方法对象
Method m3 = cl1.getDeclaredMethod("add", Integer.class,Integer.class);
//打开权限
m3.setAccessible(true);
//调用方法参数1+参数2
Object invoke3 = m3.invoke(cl1.newInstance(), 10,7);
//打印结果
System.out.println(invoke3);

 运行结果:

我们还是总结一下Java机制动态调用方法的步骤:

         


五、反射如何读写属性

学会了如何使用Java机制调用方法后我们再来看看如何读写属性吧:

实例化一个Student类:

Student stu = new Student("s009","Leaf");

然后我们再来看看这个案例需求:拿到这个学生所有的属性及属性值;

这时我们平常可能就是这样做的:

需求:拿到这个学生所有的属性及属性值
	System.out.println("Sid:"+stu.getSid());
	System.out.println("Sname:"+stu.getSname());
	System.out.println("Age:"+stu.age);

是的,这样我们也能得到结果,简单快捷,但是,这样的代码也有着诸多问题:

        

5.1 这个时候我们就可以用到我们的Java反射啦:先拿到Class类类

//一切反射从类类开始
Class cl1 = stu.getClass();

 5.2 拿到当前类所有的属性对象:getDeclaredFields();

Field[] fields = cl1.getDeclaredFields();
System.out.println("属性数量:"+fields.length);

5.3 循环遍历:

注意--->当属性是私有化修饰的时候记得打开访问权限~

//循环遍历属性对象    f:每一个属性对象
for (Field f : fields) {
            //打开访问权限
            f.setAccessible(true);
            //通过属性对象拿到属性名称
            System.out.print(f.getName()+": ");
            //通过此类实例拿到当前属性对象的属性值
            System.out.println(f.get("类实例stu"));
}

运行结果:

 


 六、反射如何访问属性修饰符

当我们能够成功读写到属性值后,

这想要访问这些属性的修饰符时,

就可以使用java.lang.reflect中Modifier接口的一个方法--->getModifiers()

我们这个时候回到上一标题获取属性值的循环遍历步骤:

        //一切反射从类类开始
		Class cl1 = stu.getClass();

		//当前类所有的属性对象
		Field[] fields = cl1.getDeclaredFields();
		
		//循环遍历属性对象	f:每一个属性对象
		for (Field f : fields) {
			//打开访问权限
			f.setAccessible(true);
		}

这个时候我们就用属性对象点getModifiers()

//循环遍历属性对象	f:每一个属性对象
for (Field f : fields) {
	//打开访问权限
	f.setAccessible(true);
    //获取属性的修饰符
    int i = f.getModifiers();
}

它返回的是一个修饰符整型数字,很难分辨这是什么修饰符,

于是我们可以用Modifier接口的toString(修饰符数字)方法转换为修饰符:

Modifier.toString(修饰符数字)

//循环遍历属性对象	f:每一个属性对象
for (Field f : fields) {
	//打开访问权限
	f.setAccessible(true);
    //获取属性的修饰符
    int i = f.getModifiers();
    System.out.println(f.getName()+"的修饰符是:"+Modifier.toString(i));
}

我们运行看看:


OK,今天Leaf的学习笔记分享就到这里啦,后面也还会有更多的Java学习分享,喜欢的可以关注一起学习噢~有问题都可以私信俺!我们下次再见啦!!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/981450.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号