---------------------- ASP.Net+Android+IOS开发、.NET培训、期待与您交流! ----------------------
概念:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
java反射:就是把java类中的各种成分映射成相应的java类
众多的java类用什么表示呢?Class ,每一个java类,类的名字,类属于哪个包,类的成员变量,类的方法,类的子类
如何得到各个字节码对应的实例对象(Class类型)
1>类.class
2>对象.getClass()
3>Class的静态方法forName("类名")
Class.forName("java.lang.String")
作用:返回字节码
返回的方式:
1>类的字节码已经加载到内存中,只有找到那份字节码返回就可以
2>java虚拟机还没有这边字节码,用类加载器加载进来,把加载进来的字节码缓存到java虚拟机中,
后面只要直接返回就可以
九个预定义Class实例对象
- 八个基本类型加void.class
Constructor类代表某个类中的一个构造方法
1>得到某个类所有的构造方法:
例子:Constructor[] constructor = Class.forName("java.lang.String").getConstructor();
2>得到某一个的构造方法
例子:Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
3>创建实例对象
通常方式: String str = new String(new StringBuffer("abc"));
反射方式: String str = (String)constructor.newInstrance(new StringBuffer("abc"));
Constructor.newInstance()//可以根据传入的参数,调用任意构造构造函数
例子:
import java.lang.reflect.Constructor;
public class Reflect1
{
public static void main(String[] args){
try{
Constructor constructor1 = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
String str = (String)constructor1.newInstance(new StringBuffer("abc"));
System.out.println(str.charAt(2));
}catch(Exception e){
e.printStackTrace();
}
}
}
new和newInstance的区别
在初始化一个类,生成一个实例的时候,newInstance()方法和new关键字除了一个是方法,一个是关键字外,
最主要有什么区别?它们的区别在于创建对象的方式不一样,前者是使用类加载机制,后者是创建一个新类
从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。但是使用newInstance()方法的时候,就必须保证:1、这个类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载java API的那个加载器。
现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。
最后用最简单的描述来区分new关键字和newInstance()方法的区别:
newInstance: 弱类型。低效率。只能调用无参构造。
new: 强类型。相对高效。能调用任何public构造。
通过反射创建新的类示例,有两种方式:
Class.newInstance()
Constructor.newInstance()
以下对两种调用方式给以比较说明:
Class.newInstance() 只能够调用无参的构造函数,即默认的构造函数;
Constructor.newInstance() 可以根据传入的参数,调用任意构造构造函数。
Class.newInstance() 抛出所有由被调用构造函数抛出的异常。
Class.newInstance() 要求被调用的构造函数是可见的,也即必须是public类型的;
Constructor.newInstance() 在特定的情况下,可以调用私有的构造函数。
成员变量的反射
Filed类代表成员变量
例子:
import java.lang.reflect.*;
public class Reflect2
{
public static void main(String[] args){
ReflectDemo r = new ReflectDemo(3,5);
//先得到类的字节码
try{
Field fieldX = r.getClass().getField("x");
System.out.println(fieldX.get(r));
Field fieldY = r.getClass().getField("y");
System.out.println(fieldY.get(r));
}catch(Exception e){
e.printStackTrace();
}
}
}
class ReflectDemo
{
public int x;
public int y;
public ReflectDemo(int x,int y){
this.x = x;
this.y = y;
}
}
成员方法的反射
Method类代表某个类中的一个成员方法
得到类中的某一个方法
例子:
Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class);
调用方法:
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str,1));
如果传递给Method对象的invoke()方法的一个参数为Null,这有着什么样的意义呢?
说明该Method对象对应的一个静态方法
Method类代表某个类中的一个成员方法
得到类中的某一个方法
例子:
Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class);
调用方法:
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str,1));
如果传递给Method对象的invoke()方法的一个参数为Null,这有着什么样的意义呢?
说明该Method对象对应的一个静态方法
例子:
import java.lang.reflect.*;
public class Test6
{
public static void main(String[] args)
{
try{
//反射方式创建对象
Class c = Class.forName("ReflectDemo");
ReflectDemo r = (ReflectDemo)c.newInstance();
//得到方法,方法名和参数类型
Method m = c.getMethod("print",String.class);
//调用invoke方法,传入对象和方法类型值
m.invoke(r,"Hello");
}catch(Exception e){
e.printStackTrace();
}
}
}
class ReflectDemo
{
public void print(String str){
System.out.println(str);
}
}
综合实例:
import java.lang.reflect.*;
/**
*第8题: 定义一个标准的JavaBean,名叫Person,包含属性name、age。
*使用反射的方式创建一个实例、调用构造函数初始化name、age,使用反射方式调用setName方法对名称进行设置,不使用setAge方法直接使用反射方式对age赋值
* @author Administrator
*
*/
public class Test8 {
public static void main(String args[]){
try{
Class
cla = Class.forName("Person");
//反射方式创建构造方法带参数的对象
Constructor
constructor = cla.getConstructor(String.class,int.class);
Person p = (Person)constructor.newInstance("wh",24);
//设置安全检查,可以访问私有构造方法
constructor.setAccessible(true);
System.out.println("----修改前----");
p.showInfo();
//反射方式调用方法
Method m = cla.getMethod("setName",String.class);
//重新设置name字段
m.invoke(p,"dahai");
//获取age字段
Field fieldAge = p.getClass().getDeclaredField("age");
//设置安全检查,可以访问私有成员变量
fieldAge.setAccessible(true);
//设置age字段值
fieldAge.set(p,25);
System.out.println("----修改后----");
p.showInfo();
}catch(Exception e){
e.printStackTrace();
}
}
}
class Person{
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
//显示person信息方法
public void showInfo(){
System.out.println("name:"+name+"\t"+"age:"+age);
}
}
---------------------- ASP.Net+Android+IOS开发、.NET培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net