Java中的反射
反射是什么?
反射是 Java 的高级特性,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。
反射就是可以在程序运行的时候动态装载类,查看类的信息,生成对象,或操作生成的对象。
反射机制的常用方法
获取类的相关信息的方法
1. Java 反射实现的关键点之 Class
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。也就是这不需要我们自己去处理创建,JVM 已经帮我们创建好了。所有的对象都有getObject()方法,可以获取这个类的Class对象;
2. getName() 方法和.getPackage()方法
String getName();返回此 Member 表示的底层成员或构造方法的简单名称。
getPackage():返回类的存放路径
3. getSuperclass() 方法
public Class<? super T> getSuperclass()
返回:此对象继承的类。
4. getConstructors() 方法
public Constructor< ? >[] getConstructors() throws SecurityException
返回:公共构造方法的 Constructor 对象数组
5. getDeclaredConstructors() 方法
public Constructor<?>[] getDeclaredConstructors() throws SecurityException
返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
这里注意,在这些get方法中,加上Declared的都是获取所有类型,没有的,只能获取public类型
返回数组中的元素没有排序,也没有任何特定的顺序。如果该类存在一个默认构造方法,则它包含在返回的数组中。 如果此 Class 对象表示一个接口、一个基本类型、一个数组类或 void,则此方法返回一个长度为 0 的数组。
返回:表示此类所有已声明的构造方法的 Constructor 对象的数组
6. getFields() 方法
public Field[] getFields() throws SecurityException`
返回:public属性的 成员变量数组
7.getField(Srtring name)
public Field getField(Srtring name)
返回:名为namen的public属性的 成员变量
8.getMethods() 方法
public Method[] getMethods() throws SecurityException
返回:表示此类中public方法的 Method 对象的数组
9.getMethod() 方法
Method Class.getMethod(String name, Class<?>... parameterTypes)
返回:对象所声明的public方法
该方法的第一个参数name是要获得方法的名字,第二个参数parameterTypes是按声明顺序标识该方法形参类型。
反射调用构造器创建对象:
Constroctor类:代表构造方法
其中的方法:
- newInstance(Object…initargs)使用构造器创建对象,传入参数
- getParameterTypes()按照声明顺序获得该构造方法的参数类型的Class数组
- setAccettible()如果构造方法的属性是私有的,不能有反射创建,传入一个参数true则允许创建
如果使用空参数构造器,就可以不获取构造器,直接使用这个类的Class对象的newInstance()
class Stu{
public int age;
public String name;
private int id;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Stu(){
}
private Stu(int age,String name){
this.age=age;
this.id=1;
this.name=name;
}
public Stu(int age,String name,int id){
this.age=age;
this.id=id;
this.name=name;
}
@Override
public String toString() {
return "Stu{" +
"age=" + age +
", name='" + name + '\'' +
", id=" + id +
'}';
}
public void show(){
System.out.println(">>>>>>>>>");
}
}
Class Cs=Stu.class;
//这里要try cath异常
Constructor ct=Cs.getConstructor();//获取空构造器
//也可以使用 Stu suu=(Stu)Cs.newInstance();
Stu suu=(Stu)ct.newInstance();//使用构造器创建对象
suu.name="hhh";
System.out.println(suu);
反射获取成员属性与赋值
Field类,对应成员变量
其中方法:
获取对象的该属性值:get(String name)
设置对象的该属性值:set(String name,Object…value)
Stu suu=new stu();
stu.name="hhh";
Field field=Cs.getField("name");
System.out.println(field.get(suu));//输出 hhh
field.set(suu,"aaaa");
System.out.println(field.get(suu));//输出 aaaa
注意,虽然可以由getDeclaredField()获得私有的属性,但是,不能直接访问私有的属性,需要设置忽略安全:
field.setAccessible(true)
反射调用方法
Method 类对应方法
执行方法
invoke( )方法,调用方法的对象,参数
Method md=Cs.getDeclaredMethod("show");//调用空show方法,参数为空
md.invoke(suu);suu对象执行他的show()方法
getName()获取方法名称
反射的作用
可以降低类一类之间的依赖,降低耦合,更多的是设计框架。但是反射会影响运行效率。
有一些私有的属性无法从外面改变,就可以使用暴力反射来访问。