反射的概念:JAVA反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象方法的功能称为java语言的反射机制。
java反射总的来说,就是动态获取类中信息。
java反射主要用于在项目后期进行功能扩展时,可以不修改原来的文件但是完成功能的修改功能,是非常有用的。
下面通过几个例子来详细了解反射机制,有些是视频中的例子,有些是自己在网上找的例子,觉得不错添加进来的
例子: (红色标注的反射常用的方法)
这个是一个person类,是我们要进行操作的类,下列的程序将会对基于这个类进行获取累名,创建实例,获取方法等等。这段程序比较简单,就不进行注释了。
Person.java:
packageitheima;
publicclass Person
{
private int age;
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;
}
private String name;
public Person(int age,String name){
super();
this.age = age;
this.name = name;
System.out.println("Personparam run..." + this.name + ":" + this.age);
}
public Person(){
super();
System.out.println("personrun");
}
public void show(){
System.out.println(name +"...show run..." + age);
}
private void privateMethod(){
System.out.println("methodrun");
}
public void paramMethod(String str,intnum){
System.out.println("paramMethod run..." + str + ":"+ num);
}
public static void staticMethod(){
System.out.println("staticmethod run...");
}
}
基于反射机制进行操作的文件:
ReflectDemo.java:
packageitheima;
importjava.lang.reflect.Constructor;
importjava.lang.reflect.Field;
importjava.lang.reflect.InvocationTargetException;
publicclass ReflectDemo {
/**
*@param args
*@throws IllegalArgumentException
*@throws ReflectiveOperationException
*/
public static void main(String[] args) throwsIllegalArgumentException, ReflectiveOperationException {
// TODO Auto-generated method stub
Demo_1();//获取字节码文件对象
Demo_2();//通过java反射机制,用Class创建类对象(反射存在的意义所在)
Demo_3();//通过java反射机制得到一个类的构造函数,并实现创造带参实例对象
Demo_4();//通过java反射机制操作成员变量
}
//例子4:通过java反射机制操作成员变量;
public static void Demo_4() throws Exception{
Stringname="itheima.Person";
//找寻该文件类文件,并加载进内存,并产生Class对象
Classclazz=Class.forName(name);
//调用Person的空参构造函数
Personperson=(Person)clazz.newInstance();
//获取私有字段
FieldpersonNameField=clazz.getDeclaredField(name");
//对私有字段的访问取消权限检查,暴力访问
personNameField.setAccessible(true);
//属性修改
personNameField.set(person,"xclyijin");
System.out.println("Demo4:修改属性之后得到属性变量的值:" + personNameField.get(person));
}
//例子3:通过java反射机制得到一个类的构造函数,并实现创造带参实例对象
private static void Demo_3() throws Exception {
Stringname="itheima.Person";
//找寻该文件类文件,并加载进内存,并产生Class对象
Classclazz=Class.forName(name);
Constructor<?>[]consturctor=clazz.getConstructors();
Personp1=(Person) consturctor[0].newInstance();
p1.setAge(30);
p1.setName("xixi");
Personp2=(Person) consturctor[0].newInstance();
p2.setAge(30);
p2.setName("mixi");
System.out.println(p1.getName()+":"+p1.getAge()+"......"+p2.getName()+":"+p2.getAge());
}
//例子2:通过java反射机制,用Class创建类的构造函数(反射存在的意义所在)
private static void Demo_2() throwsClassNotFoundException, InstantiationException, IllegalAccessException {
// TODO Auto-generated method stub
//早期:new时候,先根据被new的类的名称找寻该类的字节码文件,
//并加载进内存,并创建该字节码文件对象,接着创建
//该字节码文件的对应的Person对象,用代码表示就是Personp=new Person();
//现在代码可以书写如下:
Stringname="itheima.Person";
//找寻该文件类文件,并加载进内存,并产生Class对象
Classclazz=Class.forName(name);
//调用Person的空参构造函数
Personperson=(Person)clazz.newInstance();
person.setAge(20);
person.setName("haha");
System.out.println(person.getName()+":"+person.getAge());
}
//例子1:获取字节码文件对象
public static void Demo_1() throwsClassNotFoundException {
//可以把类的字符串名称写到配置文件中,然后读取出来
StringclassName="itheima.Person";
Classclazz=Class.forName(className);
System.out.println(clazz);
}
}