反射

来源:互联网 发布:电商html模板 仿淘宝 编辑:程序博客网 时间:2024/05/19 16:50


一:反射

反射就是把Java类中的各种成分映射成相应的java类。涉及到了一些对象,最为重要的是Class对象。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是FieldMethodContructorPackage等等。

二:如何获取一个字节码文件的Class对象呢?

2.1: 三种获取方式:


1,通过对象的getClass方法获取字节码文件对象。弊端:每次都要先有该类对象,并调用指定方法getClass才可以完成。

2,使用具备类型的一个静态属性class完成。第二种要比第一种简单,不需要对象,直接通过静态属性就可以完成。但是一样需要到了类。前两者在用的时候,必须要使用具体的已有的类来完成。

3,通过Class类中的方法forName()来完成, 这样方式要比前两种扩展性好。

 

2.2:通过三种方式实现代码:

 

package cn.itcast.reflect.p1.demo;

import cn.itcast.bean.Person;

public class ReflectDemo {

 /**
  * @param args
  * @throws ClassNotFoundException
  */
 public static void main(String[] args) throws ClassNotFoundException {

   getClassObj_3();
  
 }
 
 public static void getClassObj_3() throws ClassNotFoundException {
  
  Class clazz = Class.forName("cn.itcast.bean.Person");
  
  System.out.println(clazz.getName());
 }

 public static void getClassObj_2() {
  
  //每一种数据类型都有自己的描述。想要获取该类型的字节码文件对象。直接通过一个静态的属性就可以完成。
  Class clazz = Person.class;
  
  System.out.println(clazz.getName());
  
  
 }

 public static void getClassObj_1(){
  
  //使用对象的getClass方法。
  Person p = new Person();
  
  Class clazz1 = p.getClass();
  
//  System.out.println(clazz1.getName());
  Person p2 = new Person();
  Class clazz2 = p2.getClass();
  
  System.out.println(clazz1 == clazz2);
  
 }

}

三:Constructor

3.1:Constructor代表某个类中的一个构造方法
得到某个类所有的构造方法:
Ø例子:Constructor [] constructors=Class.forName("java.lang.String").getConstructors();
得到某一个构造方法:
Ø例子:      Constructorconstructor =Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);

  //获得方法时要用到类型

创建实例对象:
Ø通常方式:Stringstr = new String(newStringBuffer("abc"));
Ø反射方式:Stringstr = (String)constructor.newInstance(newStringBuffer("abc"));

  //调用获得的方法时要用到上面相同类型的实例对象

Class.newInstance()方法:
Ø例子:Stringobj = (String)Class.forName("java.lang.String").newInstance();
Ø该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
Ø该方法内部的具体代码是怎样写的呢?用到了缓存机制来保存默认构造方法的实例对象。

3.2:具体代码实现Constructor类

package cn.itcast.reflect.p1.demo;

import java.lang.reflect.Constructor;

import cn.itcast.bean.Person;

public class ReflectDemo2 {

 /**
  * @param args
  */
 public static void main(String[] args)throws Exception {

  createObject();
 }
 
 //演示根据指定的Class对象创建该类对象。
 public static void createObject_2() throws Exception{
  
//  Person p = new Person("lisi",20);
  
  
  Class clazz = Class.forName("cn.itcast.bean.Person");
  
  //获取指定的构造函数。  
  Constructor constructor = clazz.getConstructor(String.class,int.class);
  
  //通过指定的构造器对对象进行实例化。
  Object obj = constructor.newInstance("lisi",20);
  
  
  
  
 }
 
 
 //演示通过Class对象创建对象。
 
 public static void createObject()throws Exception{
  
  Class clazz = Class.forName("cn.itcast.bean.Person");
  /*
   * 获取字节码文件的目的是,创建该类的对象。
   */
  Object obj = clazz.newInstance();
  
  
  /*
   * 1,加载Person.class文件。
   * 2,在对内存中创建一个Person类型的对象。
   * 3,会调用空参数的构造函数进行对象的初始化。
   */
  new Person();
 }

}

四:Feild类

4.1: Field代表某个类中的一个成员变量

 

4.2:代码实现:

package cn.itcast.reflect.p1.demo;

import java.lang.reflect.Field;

public class ReflectDemo3 {

 /**
  * @param args
  * @throws Exception
  * @throws NoSuchFieldException
  * @throws ClassNotFoundException
  */
 public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, Exception {

  /*
   * 演示:获取类中的字段。 feild
   */
  
  getDemo_1();
  
 }
 
 public static void getDemo_1() throws ClassNotFoundException, Exception, NoSuchFieldException{
  
  Class clazz = Class.forName("cn.itcast.bean.Person");
  
  //获取私有字段。
  Field field = clazz.getDeclaredField("age");
  
  //获取该字节码文件的描述类的对象。
  Object obj = clazz.newInstance();
  
  //设置一下对私有的访问权限检查取消。
  field.setAccessible(true);
  
  field.set(obj, 23);
  
  System.out.println(field.get(obj));
  
  
  
//  Person p = new Person();
//  p.age = 29;
 }

}

五:Method类

5.1:Method代表某个类中的一个成员方法

得到类中的某一个方法:

Ø例子:      MethodcharAt =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对象对应的是一个静态方法!
jdk1.4jdk1.5invoke方法的区别:
ØJdk1.5public Object invoke(Objectobj,Object...args)
ØJdk1.4public Object invoke(Objectobj,Object[]args),即按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别对应被调用方法中的一个参数,所以,调用charAt方法的代码也可以用Jdk1.4改写为charAt.invoke(“str”, new Object[]{1})形式。
5.2:代码实现

package cn.itcast.reflect.p1.demo;

import java.lang.reflect.Method;

public class ReflectDemo4 {

 /**
  * @param args
  * @throws Exception
  */
 public static void main(String[] args) throws Exception {

  /*
   * 对方法反射。
   */
  getMethodDemo_3();
 }

 // 获取静态方法。
 public static void getMethodDemo_3() throws Exception {
  Class clazz = Class.forName("cn.itcast.bean.Person");

  Method method = clazz.getMethod("staticShow",null);
  
  method.invoke(null, null);
 }

 // 获取带参数的方法。
 public static void getMethodDemo_2() throws Exception {

  Class clazz = Class.forName("cn.itcast.bean.Person");

  Method method = clazz.getMethod("paramShow", String.class, int.class);

  Object obj = clazz.newInstance();

  method.invoke(obj, "wangwu", 27);
 }

 // 获取公有的无参数的方法。
 public static void getMethodDemo() throws Exception {

  Class clazz = Class.forName("cn.itcast.bean.Person");

  Method method = clazz.getMethod("show", null);

  Object obj = clazz.newInstance();

  method.invoke(obj, null);
  // Person p = new Person();
  // p.show();

 }

}

原创粉丝点击