java反射总结
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()
得到异常类型;
二、反射机制的理解
反射的真正目的是让
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
它的实例
,
但是通过反射可以
;
转载于:https://blog.51cto.com/13423770746/347139