黑马程序员--反射知识小结

本文详细解析了Java反射机制的核心概念,包括Class类的用途、获取Class对象的方式、Class类的方法介绍(如getModifiers、getInterfaces、getDeclaredFields等),以及如何通过反射机制访问对象的属性和方法,特别强调了对私有属性和方法的访问。此外,文章还阐述了反射在Java中的应用价值,以及其与框架开发的关系。

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

 

 ------- android培训java培训、期待与您交流! ----------

 

 

一、Class 类 :注意和关键字 class 不是一回事。 




Class:java.lang包下的;没有公开的构造方法;不允许直接创建对象;只能通过具体类获得;用来描述其他的一个类型 

Class 类的实例表示正在运行的 Java 应用程序中的类和接口 

获得一个Class对象的方式: 
1) Class c1=Class.forName("(类名=)Student"); 
2) Class c2=Student.class; 
3) Student s1=new Student(""); 
Class c3=s1.getClass(); 
不管通过哪种方式获得的,都是同一个对象;一种类型和一个Class对象一一对应;看如下程序, OuterA 是test包下的一个普通类。 

Class c1 = Class.forName("test.OuterA"); 
System.out.println(c1); 
Class c2 = OuterA.class; 
System.out.println(c2==c1);//结果为:true 
OuterA out = new OuterA(); 
Class c3 = out.getClass(); 
System.out.println(c3==c1);//结果为:true 

Class 类的方法介绍: 

1.int getModifiers() ;//得到此类的修饰符的int值; 

Modifiers.toString(int);//返回的就是那个修饰符名称; 例如: 

String modifier = Modifier.toString(c1.getModifiers()); 
System.out.println(modifier); 

2. Class[] getInterfaces() //如果此对象表示一个类,则返回值是一个数组,它包含了表示该类所实现的所有接口的对象。数组中接口对象顺序与此对象所表示的类的声明的 implements 子句中接口名顺序一致。 例如 类 ExFrame 如下: 

public class ExFrame extends JFrame implements ActionListener,Serializable{ 
public int intAtt; 
private double result; 
public void actionPerformed(ActionEvent arg0) { 
} 
} 

 

在main方法里: 

Class cc = ExFrame.class; 
Class[] interfaces = cc.getInterfaces(); 
for(int i=0; i<interfaces.length; i++){ 
System.out.println(interfaces[i]); 
} 

 

结果如下: 

interface java.awt.event.ActionListener 
interface java.io.Serializable 

3. Field[] getDeclaredFields();//得到所有属性; 
Field[] getFields();//得到所有公开属性 

Field[] fields = cc.getDeclaredFields(); 

for(int i=0; i<fields.length; i++){ 
System.out.println(fields[i]); 


结果如下: 

public int test.ExFrame.intAtt 
private double test.ExFrame.result 


4. Constructor<T> getDeclaredConstructor(Class... parameterTypes) 
... :可变长参数, 0个~多个,来决定得到哪个构造方法; 

5. Method getDeclaredMethod(String name, Class... parameterTypes) 
Method[] getDeclaredMethods() 
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类 
或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 

6. Class<?>[] getParameterTypes() 得到参数表; 
Class<?>[] getExceptionTypes() 得到异常类型; 

 

 


二、反射机制的理解 

反射的真正目的是让 JVM动态加载类,并且来调用方法和修改属性; 

并不是通过程序设置的,而是通过参数来加载类;类名不不出现在源码中; 

一般是在源代码中:创建一个对象时,才加载这个类; 

反射 不是给应用程序开发人员用的,是给框架开发人员用的; 

T newInstance() ;生成新的对象; 

Method getMethod(String name, Class... parameterTypes) 

 

 

三、属性:类Field 

Field 类封装了一个类的属性的所有描述 包括 修饰符、属性类型、属性值、属性的注释,提供了一系列 get/set 方法来获得修改属性的值 

类 Class 中有个方法:Field getField(String name) ; 可以得到 Field 

Field 中常用的方法: 

Object get(Object obj) ; 
void set(Object obj, Object value) ; 

Field f=c.getField("name"); //得到obj对象的name属性的值; 
f.get(obj); \\等价于obj.name; 
f.set(obj1,"hehe");//把obj1的f属性设置为hehe; 

 

 

四、方法: 类Method 

Method 类封装了一个类的所有方法的描述 包括 修饰符、返回类型、方法名、参数列表、注释、异常信息,还提供了 invoke 方法 来调用自己 

Method 有一个invoke方法: Object invoke(Object obj, Object... args) 
调用invoke这个方法时至少传一个对象, 
第一个参数:表示在哪个对象上调用该方法 ; 
第二个参数:表示传给该方法的参数;可以是0个或多个; 
Method m=c.getMethod("move"); //调用obj1的move方法; 
m.invoke(obj1,"hello","hehe"); //等价于相当于传统的调用:obj1.move("hello","hehe"); 

优势:是方法和方法参数都可以 通过参数传的,并不用写死在程序中; 

 

五、构造方法 : 类 Constructor<T> 

Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。 

对于无参构造方法,直接调用 Class 类的 newInstance() 方法就可以构造一个对象。 

对于有参数的构造方法,先点用 Class 类的 getConstructors() ,利用返回的 Constructor 的对象 调用 newInstance(Object obj1,...);例如 

public class ExFrame extends JFrame implements ActionListener,Serializable{ 
public int intAtt=9; 
private double result=90.0; 

public ExFrame(JPanel pane, int i){ 

} 
public void actionPerformed(ActionEvent arg0) { 
System.out.println("actionPerformed is invoked....."); 
} 
} 

Constructor [] cons = cc.getConstructors(); 
ExFrame ef = (ExFrame)cons[0].newInstance(new JPanel(), new Integer(20)); 

 

六、通过反射可以访问对象的私有属性吗? 

访问权限对java虚拟机都是无效的,对于私有属性而言,反射是可以访问到的; 
Field f = c.getDeclaredField("name"); 
f.setAccessible(true);//私有属性必须加上这个才有效 
System.out.println("obj name is: "+f.get(obj)); 

同样对私有成员方法有效:m.setAccessible(true); 
对于私有构造方法同样有效,con.setAccessible(true); 
构造方法为私有的就不能在外部new它的实例,但是通过反射可以; 

但是既然设为私有,没有特殊情况不要打破封装; 


Class:java.lang包下的;没有公开的构造方法;不允许直接创建对象;只能通过具体类获得;用来描述其他的一个类型 

Class 类的实例表示正在运行的 Java 应用程序中的类和接口 

获得一个Class对象的方式: 
1) Class c1=Class.forName("(类名=)Student"); 
2) Class c2=Student.class; 
3) Student s1=new Student(""); 
Class c3=s1.getClass(); 
不管通过哪种方式获得的,都是同一个对象;一种类型和一个Class对象一一对应;看如下程序, OuterA 是test包下的一个普通类。 

Class c1 = Class.forName("test.OuterA"); 
System.out.println(c1); 
Class c2 = OuterA.class; 
System.out.println(c2==c1);//结果为:true 
OuterA out = new OuterA(); 
Class c3 = out.getClass(); 
System.out.println(c3==c1);//结果为:true 

Class 类的方法介绍: 

1.int getModifiers() ;//得到此类的修饰符的int值; 

Modifiers.toString(int);//返回的就是那个修饰符名称; 例如: 

String modifier = Modifier.toString(c1.getModifiers()); 
System.out.println(modifier); 

2. Class[] getInterfaces() //如果此对象表示一个类,则返回值是一个数组,它包含了表示该类所实现的所有接口的对象。数组中接口对象顺序与此对象所表示的类的声明的 implements 子句中接口名顺序一致。 例如 类 ExFrame 如下: 

public class ExFrame extends JFrame implements ActionListener,Serializable{ 
public int intAtt; 
private double result; 
public void actionPerformed(ActionEvent arg0) { 



在main方法里: 

Class cc = ExFrame.class; 
Class[] interfaces = cc.getInterfaces(); 
for(int i=0; i<interfaces.length; i++){ 
System.out.println(interfaces[i]); 
} 

 
结果如下: 

interface java.awt.event.ActionListener 
interface java.io.Serializable 

3. Field[] getDeclaredFields();//得到所有属性; 
Field[] getFields();//得到所有公开属性 

Field[] fields = cc.getDeclaredFields(); 

for(int i=0; i<fields.length; i++){ 
System.out.println(fields[i]); 


结果如下: 

public int test.ExFrame.intAtt 
private double test.ExFrame.result 


4. Constructor<T> getDeclaredConstructor(Class... parameterTypes) 
... :可变长参数, 0个~多个,来决定得到哪个构造方法; 

5. Method getDeclaredMethod(String name, Class... parameterTypes) 
Method[] getDeclaredMethods() 
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类 
或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 

6. Class<?>[] getParameterTypes() 得到参数表; 
Class<?>[] getExceptionTypes() 得到异常类型; 



同样对私有成员方法有效:m.setAccessible(true); 
对于私有构造方法同样有效,con.setAccessible(true); 
构造方法为私有的就不能在外部new它的实例,但是通过反射可以;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值