当前位置: 首页 > news >正文

反射概率以及一些基本API的使用

请问,获取对象有几种方式?

1、通过构造函数来new一个对象;

2、通过clone来克隆一个对象;

3、通过序列化反序列化来构建一个对象;

4、通过反射来创建对象;a、通过Class类来创建;b、通过Constructor类来创建;

什么是反射

JAVA反射机制是指在运行状态(非编译状态)中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

说的直白点,就是我们可以通过反射机制,来把类的各个组成部分(属性、构造函数、方法)给获取到

反射能干嘛?

1:获取类的相关信息

2:动态调用方法

3:动态构造对象

Class类

我们发现该类没有构造函数,我们可以通过forName静态方法来获取到类对象。

Class类提供的API分类

获取到类信息的相关方法

获取到类中属性相关的方法

获取到类中方法相关的方法

获取到类中构造器相关的方法

反射相关类的简介

此处并没有列出这三个类中的所有方法, 只是这几个方法能够反映出该类的特点, 具体方法请参考API文档。

Field代表类的成员变量(成员变量也称为类的属性)

Method代表类的方法

Constructor类

反射案例:反射操作Book类

反射操作的Book类

class Book{
	//提供一个公开访问权限的属性
	public int bid;
	//提供一个私有的属性;
	private String bname;
	//提供一个默认的属性
	double price;
	//构建多个不同参数的构造函数
	public Book() {
		System.out.println("这是无参构造函数");
	}
	public Book(String bname) {
		this.bname = bname;
		System.out.println("这是一个参数构造函数");

	}
	public Book(int bid, String bname) {
		this.bid = bid;
		this.bname = bname;
		System.out.println("这是两个参数构造函数");

	}
	//构建两个方法,分别是私有的和共有的方法
	public void read(String bname) {
		System.out.println(bname+"这是一本好书,需要好好读!");
	}
	
	private void write(String content) {
		System.out.println("我在写一本书,这本书的内容是:"+content);
	}
	public String getBname() {
		return bname;
	}
	public void setBname(String bname) {
		this.bname = bname;
	}
	@Override
	public String toString() {
		return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
	}
}

三种方法获得字节码对象

		//获取到类的字节码对象
		//1、通过Class.forName来获取到指定路径下的类的字节码对象
		Class<?> classObj1 = Class.forName("lession14.reflect.Book");
		//2、通过对象来获取
		Book bookObj2 = new Book();
		Class<?> classObj2 =bookObj2.getClass();
		//3、通过类来获取到指定类的字节码对象
		Class<?> classObj3 = Book.class;
		//1.1、我们可以通过字节码对象来做哪些事情
		//1.1.1、获取到实例对象
		Book bookObj1 = (Book)classObj1.newInstance();
		System.out.println(bookObj1);
		//1.1.2、获取到类的相关信息
		System.out.println(classObj1.getName());
		System.out.println(classObj1.getPackage());

操作属性,构造函数以及方法

public class ReflectDemo {
	public static void main(String[] args) throws Exception {
		//获取到类的字节码对象
		//1、通过Class.forName来获取到指定路径下的类的字节码对象
		Class<?> classObj1 = Class.forName("lession14.reflect.Book");
		//2、通过对象来获取
		Book bookObj2 = new Book();
		Class<?> classObj2 =bookObj2.getClass();
		//3、通过类来获取到指定类的字节码对象
		Class<?> classObj3 = Book.class;
		//1.1、我们可以通过字节码对象来做哪些事情
		//1.1.1、获取到实例对象
		Book bookObj1 = (Book)classObj1.newInstance();
		System.out.println(bookObj1);
		//1.1.2、获取到类的相关信息
		System.out.println(classObj1.getName());
		System.out.println(classObj1.getPackage());
		//1.1.3、获取到相关的属性对象
		//1.1.4、获取到相关的方法对象
		//1.1.5、获取到相关的构造函数对象
		//4、通过字节码对象和对应的实例对象来操作他们的属性
//		operateField(classObj1,bookObj1);
		//5、通过字节码对象和对应的实例对象来操作他们的构造函数
//		operateConstructor(classObj1,bookObj1);
		//4、通过字节码对象和对应的实例对象来操作他们的方法
		operateMethod(classObj1,bookObj1);
	}

	private static void operateMethod(Class<?> classObj, Book book) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//1、获取到一个公有方法
		Method read = classObj.getMethod("read", String.class);
		System.out.println(read.getName());
		//2、调用该方法
		read.invoke(book, "红楼梦");
		//3、获取到私有方法
		Method write = classObj.getDeclaredMethod("write", String.class);
		write.setAccessible(true);
		write.invoke(book, "今天天气真好");
		//4、获取所有方法
		Method [] methods = classObj.getDeclaredMethods();
		for(Method method:methods) {
			System.out.println(method.getName());
		}
	}

	private static void operateConstructor(Class<?> classObj, Book book) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//1、使用字节码对象来调用无参的构造函数对象
		Constructor<?> constructor = classObj.getConstructor();
		//查看下构造函数对象
		System.out.println(constructor);
		//2、通过刚刚创建的无参构造函数对象来创建一个实例对象
		Book book1 = (Book)constructor.newInstance();
		//3、输出看是否正常
		System.out.println(book1);
		//4、使用字节码对象来调用有参的构造函数对象
		Constructor<?> constructor1 = classObj.getConstructor(String.class);
		//注意:通过构造函数对象创建实例对象的时候,参数一定要进行对应匹配,否则会报非法参数异常!
		Book book2 = (Book)constructor1.newInstance("三国演义");
		System.out.println(book2);
	}

	private static void operateField(Class<?> classObj, Book book) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		//1、首先为Book对象中的公开属性进行一个赋值
		book.bid = 1001;
		//2、通过字节码对象来获取到该属性
		Field bidField = classObj.getField("bid");
		//3、通过对象来获取到刚刚通过字节码对象拿到的属性对象
		Integer bid = (Integer) bidField.get(book);
		//4、测试,是否能获取到book对象中的bid的属性值
		System.out.println(bid);
		//5、测试通过属性对象来更改属性值
		bidField.set(book, 1002);
		//6、测试,查看是否更改成功
		System.out.println(book.bid);
		//7、如果属性不是public修饰呢?
		//8、先把私有的属性值给进行一个赋值
		book.setBname("西游记");
//		Field bnameField = classObj.getField("bname");//报错,找不到该属性的异常错误
		//9、通过专门获取非公有属性的方法来拿到具体的属性对象
		Field bnameField = classObj.getDeclaredField("bname");
		//10、设置私有的属性权限可见
		bnameField.setAccessible(true);//暴力破解私有特点
		//11、来拿到指定的Field对象在指定实例对象里面的值
		String bname = (String)bnameField.get(book);
		//12、测试是否能够正常的获取到类里的私有属性值
		System.out.println(bname);
		//13、只要你的属性是非公有的,你都需要通过getDeclaredField来获取
		book.price = 19.9;
		Field priceField = classObj.getDeclaredField("price");
//		Field priceField = classObj.getField("price");
//		priceField.setAccessible(true);//暴力破解私有特点
		double price = (double)priceField.get(book);
		System.out.println(price);
		//14、同时获取到所有的属性
		Field [] fields = classObj.getDeclaredFields();
		for(Field field:fields) {
			System.out.println(field.getName());
		}
	}
}

相关文章:

  • BUU38 [RoarCTF 2019]Easy Java1
  • DeePseek结合PS!批量处理图片的方法教程
  • AnythingLLM打造私有知识库
  • 微软AutoGen高级功能——Serializing Components
  • 【原创】springboot+vue考试考场座位安排管理系统设计与实现
  • 【架构设计】微服务架构模型:常见模型的对比和分析
  • 更高效实用 vscode 的常用设置
  • 全排列(力扣46)
  • RFM模型-数据清洗
  • 基于mediapipe深度学习的手势数字识别系统python源码
  • 20250214实测飞凌的OK3588-C_Linux5.10.209+Qt5.15.10_用户资料_R1的USB2.0的速度为29.0 MB/s
  • 香港VPS服务器如何排查和修复 MySQL 数据库连接失败的问题
  • 从图像中提取的每行数字作为一张完整的图片,而不是每个数字单独成为一张图片
  • 教程:使用 Vue 3 和 arco 实现表格合并
  • MySQL 数据库定时任务及进阶学习
  • UE_C++ —— Metadata Specifiers
  • Redis——优惠券秒杀问题(分布式id、一人多单超卖、乐悲锁、CAS、分布式锁、Redisson)
  • 【目标检测json2txt】label从COCO格式json文件转YOLO格式txt文件
  • mysql开启gtid并配置主从
  • Windows 11 下 Ollama 安装与 OpenWebUI 调用 DeepSeek-R1 的详细指南
  • 白玉兰奖征片综述丨海外剧创作趋势观察:跨界·融变·共生
  • 马上评|训斥打骂女儿致死,无暴力应是“管教”底线
  • 湃书单|澎湃新闻编辑们在读的14本书:后工作时代
  • ESG考证虚火:相比证书,知识结构+实战经验更重要
  • 美国调整对华加征关税
  • 微软将在全球裁员6000人,目标之一为减少管理层