反射

本文介绍了Java反射机制,它能在运行状态动态获取类信息、调用对象方法。核心是从获得类对象开始,获取对象有三种方式。还阐述了利用反射进行实例化,包括调用不同构造函数,以及动态方法调用和读写属性,涉及无参、有参及私有情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、反射的概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

1.1 什么是反射
反射java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法

1.2反射的核心
一切反射相关的代码都从获得类对象开始

获取对象的方式

在此之前我们需要有一个实列化的包
分为三种

1:通过对应类实列(java.lang .Class)的类实列(Stuent.class)的方法获取

 Student stu=new Student();//获取Student 的class的一个实列
   Class clz=stu.getClass();//获得Class

2:通过class.forName(“类的全路径”);JDBC的驱动加载用到反射技术
//Class clz = Class.forName("com.zking.reflect.Student");

3:类实列.class 做通用查询的时候用到

Class clz=Student.class;//3 作为参数来传

利用反射进行实列化

思考:
利用反射经行实列化
能够获取Students.class
如何通过Student.class拿到Student的一个实列?
反射的好处?
能够将未知的类经行实列化
注意:
① ClassNotFoundException(类名错|少jar包)
② 同一类的、类对象只会创建一个

在这里插入图片描述
1.调用无参的构造函数

	Class clz=Student.class;
	//通过反射的方式调用无参构造函数
	Student stu = (Student) clz.newInstance();//将未知的类经行实列化

2.调用含有一个参的构造函数

//通过反射的方式调用带有一个参数的构造器来实列化  Class
//(String.class是对class的一种实列 描述了所有带class的文件)
	Constructor c = clz.getConstructor(String.class);//可变参数     
	Student stu = (Student) c.newInstance("s001");

3.调用两个参的构造函数

//通过反射的方式调用带有两个参数的构造器来实列化  Class
//(String,class是对class的一种实列   描述了所有带class的文件)
		Constructor c = clz.getConstructor(String.class,String.class);//可变参数       
		Student stu = (Student) c.newInstance("s001","zs");

4.调用私有化的构造函数

//通过反射的的方式调用私有化的构造器来实列化对象
		Constructor c = clz.getDeclaredConstructor(Integer.class);//可变参数  
		c.setAccessible(true);//打开访问权限
		Student stu =(Student) c.newInstance(23);

getConstructor 与getDeclaredConstructor 的区别
getConstructor 获取到的是public 修饰的
getDeclaredConstructor获得的是所有的构造器

动态方法调用

在这里插入图片描述
//第一个参数指的是,类类的类实列的类实列
//第二个参数指的是调用方法所携带的可变参数
//Method类invoke方法的返回值就是被调用的方法的返回值
//如果被调用的方法不具备返回值,那么就返回null

1.无参的构造函数

		Class clz=Student.class;
		Method m = clz.getDeclaredMethod("hello");//可变参数可传可不传
		//m.invoke(clz.newInstance());//当前对象的实列(具体的实列)
		System.out.println(m.invoke(clz.newInstance()));

2.含有一个参数的构造函数

		Method m=clz.getDeclaredMethod("hello", String.class);
		Object invoke = m.invoke(clz.newInstance(), "xxx");

3.含有私有化的构造函数

		Method m=clz.getDeclaredMethod("add", Integer.class,Integer.class);
		m.setAccessible(true);//打开访问权限
		Object invoke = m.invoke(clz.newInstance(), 20,5);
		System.out.println(invoke);

读写属性

1.获取属性值

public static void main(String[] args) throws Exception {
		Student stu=new Student("s001","zs");
		stu.age=23;
		Class clz=stu.getClass();
		
		//获取属性值  获取
		Field[] fields = clz.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			System.out.println(field.getName()+":"+ field.get(stu));	
		}

2.设置属性值 共有的

Field field = clz.getDeclaredField("age");
		field.set(stu, 45);
		System.out.println(stu.age);

3.设置属性值 私有的

Field field = clz.getDeclaredField("sname");
		field.setAccessible(true);
		field.set(stu, "ls");
		System.out.println(stu.getSname());

举例:
思考
封装后的类,内部的属性一定不能被外界访问吗

内部私有化的方法一定不能够被外界所调用吗?

在这里插入图片描述
结果的显示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值