`
newjueqi
  • 浏览: 12063 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

JDK5.0新特性(2)——反射

    博客分类:
  • java
阅读更多

【文章标题】JDK5.0新特性(2)——反射

【文章作者】曾健生

【作者邮箱】zengjiansheng1@126.com

【作者QQ190678908

【作者博客】http://blog.csdn.net/newjueqi

                     http://newjueqi.iteye.com/

【作者声明】欢迎转载文章,但转载请保留文章的完整性以及注明文章的出处。

 

*******************************************************************************

JDK5.0后,Sunjava新增一些特性来简化开发,本文主要介绍一个重要的特性:

反射。

       使用反射技术,必须要导入类库java.lang.reflect,与Class类一起对反射技术进行支持, 其中包含了Field(属性)类,Method(方法)类和Constructor(构造函数)类。

      

       每个类被加载后,系统会为该类创建一个Class对象,通过获取该Class对象,就能在JVM中访问该类。通过上面的描述,可以得到一个结论:Class对象不是在编译时就存在,是在运行时才存在的。

 

学生类Students在下面每个例子中都需要:

 

//学生类Student

class Student

{

    private String name;    //学生姓名

    private Integer age;    //学生年龄定义为Integer,理由在创建类的实例段落中有说明

    public Student()

    {

        System.out.println("这是默认的构造函数");

    }

    public Student(String name, Integer age) {

        this.name = name;

        this.age = age;

        System.out.println("这是带两个参数的构造函数");

    }

 

    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;

    }

   

    public void getInfo()

    {

        System.out.println( "学生姓名:"+name+" 学生年龄:"+age );

    }

   

}

 

 

1. 获取一个类的Class对象有以下三种方法:

(1)       通过Class类的forName静态方法

(2)       调用某个类的class属性

(3)       通过某个对象的getClass()方法

 

我们通过具体的实例体现一下这三种方法的优缺点:

 

//获取Class对象的演示代码

public static void getClassObj()

    {

       //1    通过Class类的forName静态方法获取Class对象

       Class cla1=Class.forName("Student");

      

       //2    调用Stutdent类的class属性

       Class cla2=Student.class;

      

       //(3    调用Student对象sudgetClass()方法

        Student std=new Student( "zhangsan",20 );

       Class cla3=std.getClass();  

   

    }

通过以上的比较可得知,用第一种方法最灵活,通过类名就可获取Class对象, forName()方法中是传入的字符串可通过参数的形式获取,极大提高了程序的灵活性,而且这个方法可在运行时动态地获取相应的Class对象,本人曾写过一篇博文《改良用简单工厂模式构造的计算器代码》(http://blog.csdn.net/newjueqi)就使用了这个方法。最麻烦的是第三种方法,获取Class对象必须要先创建一个类的实例。

 

2. 创建类的实例在反射技术中有两种方法:

(1)       取得Class对象,通过Class对象的newInstance()创建该Class 对象对应类的实例。这种方法要求该类必须要有一个默认构造函数。

(2)       先获取Class对象中的Constrcutor对象,然后通过Constrcutor对象的newInstance() 方法来创建该 Class 对象对应类的实例,这种方法可选择需要调用的是哪个构造函数。

 

演示代码如下:

 

    //获取Class对象对应类实例的演示代码

    public static void getInstanceObj() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException

    {

       //获取Class对象

       Class cla=Class.forName("newjueqi.net.csdn.test.Student");

      

       /*

       1.通过Class对象的newInstance()创建该Class 对象对应类的实例,

       使用的是默认构造函数

       */

        Object obj_1=cla.newInstance();

      

       /*

       2.通过Constrcutor对象的newInstance() 方法

       来创建该 Class 对象对应类的实例,使用的是带两个参数的构造函数

       */

       //选择带两个参数的构造函数

        Constructor constructor=cla.getConstructor( String.class

                                                ,Integer.class );

       //通过Constructor类的newInstance() 方法来创建该 Class 对象对应类的实例

        Object obj=constructor.newInstance( "zhangsan", 20 );

    }

 

使用方法2需要注意一下,如果在Student类中把年龄(age)的类型定义为int的话,那么是无法通过Constrcutor对象的newInstance() 方法调用有两个参数的构造函数来创建该 Class 对象对应类的实例,因为基本数据是没有Class对象,所以在定义时把年龄(age)的类型定义为Integer

 

3. 使用反射调用方法

分为两个步骤:

1.       通过Class对象的getMethods()或getMethod()获取一个全部方法或指定的方法。

2.       通过Methods对象的invoke()方法调用对应的方法。

 

下面的代码演示了如果通过获取getMethods()Student类中所有方法:

 

    //获取Studnet类中的所有方法

    public static void getStudentMethods() throws ClassNotFoundException

    {

       //获取Class对象

       Class cla=Class.forName("newjueqi.net.csdn.test.Student");

      

       //获取Studnet类中的所有方法

        Method method[]=cla.getMethods();

      

        for( Method meth:method )

       {

           System.out.println( meth.getName() );

       }

    }

 

/****

输出结果:

getAge

setAge

getName

setName

hashCode

getClass

wait

wait

MsoNormal

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics