黑马程序员——反射学习总结(上)

首先要明白反射是用来干嘛的。“反射就是把JAVA类中的各种成分映射成相应的JAVA类”,照我的理解,正常来说是先有类才能有对象,反射就是先有对象,然后再找到对象对应的类的过程。那如何通过对象找到类呢?就要通过字节码了。Class代表所有JAVA类,而Class类不同的实例对象则对应这不同的JAVA类,这些类也会有不同的实例对象,但都是属于同一个类,而不同的类会有不同的标识特性,这个就是字节码了,只要知道了某个对象对应的类的字节码,也就能知道这个类是什么类了。得到类的字节码的方式一般有三种——1:类名.class;2:对象.getClass();3:Class.forName("类名")。然后通过反射API类可以得到对应类中的成员方法的实例对象,构造方法的实例对象,成员变量的实例对象。

Constructor类:

当得到某个类的字节码后,就能通过这个类的字节码得到此类的构造方法的实例对象,如下所示:

		Class clazz = String.class;//得到String类的字节码
		Constructor cons = clazz.getConstructor(StringBuffer.class);//通过字节码得到String类的某个构造方法

因为类中的同名的构造方法可能不止一个,所以getConstructor()方法的参数就对应了不同的构造方法的参数,但必须得是Class类型,即某个类的字节码。

获得类的构造方法后,便能通过这个方法生成实例对象,如下所示:

		Class clazz = String.class;//得到String类的字节码
		Constructor cons = clazz.getConstructor(StringBuffer.class);//通过字节码得到String类的某个构造方法

当得到了构造方法的实例cons后,就能通过.newInstance()方法生成类的实例对象,这里需要注意的是newInstance()方法的参数不再是字节码,而是实例变量,和getConstructor()方法中对应的实例变量。因为这样生成的类的对象是Object类型的,如果要将其赋值给某个对象必须进行强制转换

String string = (String)cons.newInstance(new StringBuffer("abc")); 

还有一点者的注意的是,Class中也有一个newInstance()方法,能省略中间先获得构造方法的对象,再通过构造方法对象创建实例的过程,直接通过Class调用无参数的构造方法创建实例。如:

clazz.newInstance();

Field类:

除了能得到某个类的构造方法的实例变量外,还能获得获得类的成员变量的实例,如下所示:

	public static void main(String[] args) throws Exception{
		
		
		Person2 person = new Person2();
		Field field = person.getClass().getField("age");
		System.out.println(field.get(person));
		field.set(person, 2);
		System.out.println(field.get(person));
	}

}

class Person2{
	public int age;
}

field为Person2这个类的age变量的实例,当获得这个实例后便能对person这个Person2实例中的age变量进行操作。

运行结果为:

0

2

因为field.set()方法对age变量进行了赋值,所以第二次输出的结果为2。

这里需要注意的是,如果类的成员变量为private或default,Field是看不见且不能操作这个变量的,需要进行如下操作:

		Person2 person = new Person2();
		Field field = person.getClass().getDeclaredField("age");
		field.setAccessible(true);
		System.out.println(field.get(person));
		field.set(person, 2);
		System.out.println(field.get(person));

运行结果依旧为:

0

2


Method类:

通过geMethod()方法也能获得类的成员方法的对象,如下:

		String string = "abc";
		Method method = string.getClass().getMethod("charAt", int.class);
		System.out.println(method.invoke(string, 2));

运行结果为:c

通过getMethod(arg0,arg1)方法获得成员方法的对象,arg0参数为成员方法的方法名,因为可能有许多重名的成员方法,所以arg1为方法的参数,同样也为类,而非类的实例,即应该为类.class。然后便可以通过invoke(arg0,arg1)调用此方法,arg0为调用此方法的对象,如果为null的话即为静态方法,arg1为调用方法时传入的参数,这里应该为类的实例而非类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
黑马程序员的tb_brand是指在JavaWeb基础教程中创建的一个表。这个表是用来存储品牌信息的,具体的表结构和数据类型需要和JavaBean类中的成员变量保持一致。\[1\]在这个教程中,使用了Maven来构建项目,并且使用了MyBatis作为持久层框架,通过配置pom.xml文件来引入相关依赖。\[2\] Maven是一个用于管理和构建Java项目的工具,它提供了一套标准化的项目结构、构建流程和依赖管理机制。\[3\] #### 引用[.reference_title] - *1* [【JAVAWEB开发】黑马程序员java web案例资料(含Element的删除与修改)](https://blog.csdn.net/aasd23/article/details/126940147)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [黑马程序员-MyBatis 框架-最全入门笔记、阿伟看了都得说真大、真细、真全!!!](https://blog.csdn.net/qq_57383364/article/details/128103058)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [JavaWeb——黑马程序员课程笔记](https://blog.csdn.net/King_ZACC/article/details/128573804)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值