快速教你十分钟学完反射
反射是什么
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射机制的语言。最近,反射机制也被应用到了视窗系统、操作系统和文件系统中。
反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学赋予了反射概念新的含义,但是,从现象上来说,它们确实有某些相通之处,这些有助于我们的理解。在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。可以看出,同一般的反射概念相比,计算机科学领域的反射不单单指反射本身,还包括对反射结果所采取的措施。所有采用反射机制的系统(即反射系统)都希望使系统的实现更开放。可以说,实现了反射机制的系统都具有开放性,但具有开放性的系统并不一定采用了反射机制,开放性是反射系统的必要条件。一般来说,反射系统除了满足开放性条件外还必须满足原因连接(Causally-connected)。所谓原因连接是指对反射系统自描述的改变能够立即反映到系统底层的实际状态和行为上的情况,反之亦然。开放性和原因连接是反射系统的两大基本要素。13700863760
Java中,反射是一种强大的工具。它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码。这使反射成为构建灵活的应用的主要工具。但需注意的是:如果使用不当,反射的成本很高。
反射具体实现
- 调用class中的构造器
- 调用class中成员变量
- 调用class中方法(私有方法)
代码块
反射具体调用的代码:
package reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import reflect.bean.Student;
/*
* 利用Class对象获取构造器
* */
public class 反射构造器 {
public static void main(String[] args) throws Exception {
//获取class对象
Class c1 = Class.forName("reflect.bean.Student");
//获取所有public修饰 的构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("*********获取所有的构造器**********");
//获取所有的构造器
Constructor[] constructors2 = c1.getDeclaredConstructors();
for (Constructor constructor : constructors2) {
System.out.println(constructor);
}
System.out.println("******获取单个无参构造器*************");
//获取单个无参公共构造器
Constructor constructor = c1.getConstructor();
System.out.println(constructor);
System.out.println("******获取有参数公共的构造器*************");
//获取有参数的构造器
Constructor constructor2 = c1.getConstructor(String.class,int.class);
System.out.println(constructor2);
//获取默认的或者私有的构造器
System.out.println("******获取获取默认的或者私有的构造器*************");
Constructor constructor3 = c1.getDeclaredConstructor(int.class);
//当参数值为true的时候,可以忽略访问修饰符的限制
constructor3.setAccessible(true);
System.out.println(constructor3);
System.out.println("******利用构造器创建对象*************");
//利用构造器创建对象
Object o1 = constructor.newInstance();
System.out.println(o1.toString());
//
Object o2 = constructor2.newInstance("庾浪",18);
System.out.println(o2);
//访问私有构造器
Object o3 = constructor3.newInstance(20);
System.out.println(o3+"这是private 的构造器");
//访问任何构造器
Constructor declaredConstructor = c1.getDeclaredConstructor(/*如果有参数就写参数.class*/);
declaredConstructor.setAccessible(true);
Object newInstance = declaredConstructor.newInstance();
System.out.println("***************\n*********这是获取public修饰的成员变量");
//获取所有的public修饰的成员变量
Field[] fields = c1.getFields();
for (Field field : fields) {
System.out.println(field);
}
//获取所有成员变量,不管什么修饰符修饰
System.out.println("***************\n*********这是获取private修饰的成员变量");
Field[] fields2 = c1.getDeclaredFields();
for (Field field : fields2) {
System.out.println(field);
}
//获取单个成员变量,
Field declaredField = c1.getDeclaredField("name");
declaredField.setAccessible(true);
declaredField.set(o1, "男朋友");
System.out.println(o1);
//获取public修饰的方法
System.out.println("********这是获取public修饰的方法");
Method[] methods = c1.getMethods();
for (Method method : methods) {
System.out.println(method);
}
//获取所有的方法
Method[] declaredMethods = c1.getDeclaredMethods();
//获取所有的private修饰的方法
System.out.println("********所有的private修饰的方法");
Method declaredMethod = c1.getDeclaredMethod("show", null);
System.out.println(declaredMethod);
declaredMethod.setAccessible(true);
Object invoke = declaredMethod.invoke(o1,null);
//这是方法的返回值null
System.out.println(invoke);
//这是访问有返回值 无传参的
Method declaredMethod1 = c1.getDeclaredMethod("toString", null);
Object invoke1 = declaredMethod1.invoke(o1,null);
System.out.println(invoke1);
//访问私有带参数的访问返回值
System.out.println("********访问私有带参数的访问返回值 ");
Method declaredMethod2 = c1.getDeclaredMethod("show1", String.class);
declaredMethod2.setAccessible(true);
Object invoke2 = declaredMethod2.invoke(o1,"女朋友");
System.out.println(invoke2);
}
}
这是bean中student对象,我们需要这个对象中的class文件测试
package reflect.bean;
import java.io.Serializable;
public class Student implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private int age;
public String gender;
public Student() {
}
protected Student(String name) {
this.name = name;
}
private Student(int age) {
this.age = age;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
private void show(){
System.out.println("这是student是private的私有方法打印的");
}
private String show1(String name) {
return "Student [name=" + name;
}
}
目录
用 [TOC]
来生成目录: