您的位置:首页 > 编程语言 > Java开发

Java基础知识整理三(反射机制详解…

2014-04-18 12:55 971 查看
N、Java的反射机制

   
Java程序中许多对象都在运行时会出现两种类型:编译时类型和运行时类型。Java提供了反射机制来获取运行时类的相关信息,如获知这个类中多有的方法和属性,包括私有的方法和属性,在运行时判断一个对象所属的类、创建一个类的实例,在运行时调用一个类的方法或者修改类的某个属性值等,甚至可以在运行时获取和修改这个类中私有属性的值,这些功能在普通机制中是没有办法实现的。

   
每个类被加载之后,系统就会为该类生成一个对应的且唯一的Class对象,通过该Class对象可以访问到JVM中的这个类,并获取与之相关的信息。获取一个类的Class对象有以下几种方式:一是使用Class的静态方法forName(),该方法需要传入一个字符串参数,该字符串参数的值应该是某个类的全限定类名;而是调用对象的getClass()方法,该方法是Object类中的一个方法,返回一个Class对象。三是调用否个类的class属性来获取与之相关的Class对象。

   
从Class中获取信息:Class类中提供了大量的实例方法来获取某个类的相关信息。在这里就不一一列举了,在后面的实例程序中将有介绍。

   实例1、ReflectionTest

   

package reflectionTest;

import java.lang.reflect.*;

public class ReflectionTest{

   
//定义一个加法运算方法和一个普通方法

    public
int add(int a1,int a2){

       
return a1+a2;

    }

    public
String encho(String name){

       
return "hello:"+name;

    }

    public
static void main (String[] args) throws Exception {

       
//获取某一个类对应的Class对象的方式之一,命令行参数指定:

       
Class<?>
classType=Class.forName(args[0]);

       
//每一个方法都会有与之对应的一个Method对象

       
Method[] methods=classType.getDeclaredMethods();

       
for(Method me:methods)

       
{

           
System.out.println(me);

       
}

       

       

       

       
//获取某个类对应的class对象的第二种方式:通过 类名.class 语法获得

       
Class<?>
classType2=ReflectionTest.class;

       
//获取add方法对用的Method对应对象,需要传入方法名和参数列表对应的Class对象

       
Method addMethod=classType2.getMethod("add",new
Class[]{int.class,int.class});

       
//通过这个相关Class对象获得对应类的实例

       
Object instance1=classType2.newInstance();

       
//通过该method对象来调用add方法,需要传入调用者对象和参数值,返回一个Object对象

       
Object result1=addMethod.invoke(instance1,new
Object[]{100,200});

       
//以上的方式通过反射来调用方法,其效果与通过创建对象来调用一样

       
System.out.println((Integer)result1);

       

       
//同理获encho方法对应的Method对象

       
Method enchoMethod=classType2.getMethod("encho",new
Class[]{String.class});

       
//通过Method对象来调用方法

       
Object result2=enchoMethod.invoke(instance1,new Object[]{"Hello
World!"});

       
System.out.println((String)(result2));

}

}

   实例2、ReflectionTest2.java

package reflectionTest;

import java.lang.reflect.Method;

import java.lang.reflect.Field;

import java.lang.reflect.Constructor;

 

public class ReflectionTest2{

    public
Object copy(Object object) throws Exception{

       
//获取某一类的对应的Class对象的第三种方式,通过getClass()方法来获得运行时的Class对象

       
Class<?>
classType=object.getClass();

       
//打印出获取的Class对象所关联的类型名

       
System.out.println("所要复制的类名为:"+classType.getName());

       

       

       

       
Object objectCopy=classType.getConstructor(new
Class[]{}).newInstance(new Object[]{});

       
//通过Class对象获得关联类中的所有属性

       
Field[] fields=classType.getDeclaredFields();

       
//循环调用类中的方法

       
for(int i=0;i<fields.length;i++){

           
Field field=fields[i];

           
//获取某个属性的名称

           
String fieldName=field.getName();

           
//提取首字母

           
String firstLetter = fieldName.substring(0,1).toUpperCase();

           
//提取首字母的目的就是拼接成目标类中存在的方法的名称以供后面的程序获取Method对象时使用

           
//因为在Customer这个JavaBean中,set、get方法时有规律的

           
String getMethodName="get"+firstLetter+fieldName.substring(1);

           
String setMethodName="set"+firstLetter+fieldName.substring(1);

           

           
//通过getMethod()方法来获取关联类中所具有的方法对应的Method对象

           
//get方法不需要参数

           
Method getMethod=classType.getMethod(getMethodName,new
Class[]{});

           
//set方法需要传入参数,指定参数类型

           
Method setMethod=classType.getMethod(setMethodName,new
Class[]{field.getType()});

           

           
//通过Method对象调用invoke()方法来执行具体的参数,调用时要指定由哪个对象类调用和传入的参数值

           
Object value=getMethod.invoke(object,new Object[]{});

           
System.out.println("执行get方法,得到属性值为:"+value);

           
//调用set方法为副本对象的相关属性赋值

           
setMethod.invoke(objectCopy,new Object[]{value});

       
}

       
return objectCopy;

    }

    public
static void main (String[] args) throws Exception {

       
Customer cs=new Customer();

       
Customer csCopy=(Customer)new ReflectionTest2().copy(cs);

       
System.out.println(csCopy.getName()+csCopy.getAge()+"");

}

}

class Customer{

    private
Long id;

    private
String name;

    private
int age;

   

   
//使用getConstructor()来调用newInstance()时,自定义的构造方法必须声明为public权限

    public
Customer(){

       
this.id=1l;

       
this.name="zhangsan";

       
this.age=20;

    }

   

    public
void setId(Long id){

       
this.id=id;

    }

    public
Long getId(){

       
return id;

    }

   

    public
void setName(String name){

       
this.name=name;

    }

    public
String getName(){

       
return name;

    }

   

    public
void setAge(int age){

       
this.age=age;

    }

    public
int getAge(){

       
return age;

    }

}

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: