首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

java反照机制 入门 理解

2012-12-19 
java反射机制 入门 理解一、java中生成对象的方式,本人所能想到的有以下几种(以 com.knight.Employer为例)1

java反射机制 入门 理解

一、java中生成对象的方式,本人所能想到的有以下几种(以 com.knight.Employer为例)

1、使用new方式,这每个javaer都会的

?? Employer e=new Employer();

2、使用克隆方式(clone),此方式要求Employer实现cloneable接口

?? Employer e2=(Employer)e1.clone();

3、序列化方式,此方式要求Employer实现Serializable接口

?? ObjectInputStream objIn=new ObjectInputStream(in);//in为InputStream实例

?? Employer e=(Employer)objIn.readObject();

4、反射

? 反射可以有很多变体,通常有以下几种

? Class c=Class.forName("com.knight.Employer");

? Employer e=?(Employer)c.newInstance();

? 或者

? ClassLoader loader=Huma.class.getClassLoader();

? Class c=loader.loadClass("com.knight.Employer");

? Employer e=?(Employer)c.newInstance();

? 此两种方式都要求Employer有公有无参构造函数。

? 还有另外一种通过Constructor进行构造,以下详述

5、直接操作字节码,这种方式需要对class文件及虚拟机机制有深刻理解,不是一般的难

?

二、java反射api简介

以下与Huma类为例

package com.knight.test;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
public class Huma {
?public String name;
?private int age;
?private void log(){
??System.out.println("log invoke");
?}
?public Huma() {
?
?}
?
?public Huma(String name,int age) {
?? 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;
?}
}

?

java中反射机制主要使用以下几个类

Class,Constructor,Field,Method,AccessibleObject

1、Class的用法

Class可以获取关于类中所有方法,属性的信息

??? Field[] getFields()//获取Huma中声明的公有属性,包括从父类继承的

??? Field[] getDeclaredFields()//获取Huma中声明所有属性(包括私有属性),但不包含任何父类继承的属性

注意有无declared的区别,以下不在罗嗦

?

???? Field getField(String name)//获取名称为name的属性

以此类似,Class可以获取其对于的Constructor,Method信息

再举一个方法

?????Method getDeclaredMethod(String name, Class<?>... parameterTypes);此方法获取成员函数名字为name,函数的参数类型为Class<?>... parameterTypes的函数,其中parameterTypes为null或者为空数组时,表示该函数没有形参

?

?

?

public Object newInstance() //生成该类的一个对象,需有无参构造函数

public static Class forName(String className)//生成className指定的类的Class实例

2、AccessibleObject

?? AccessibleObject是一个接口,Constructor,Field,Method均实现了该接口

??

public void setAccessible(boolean?flag);该方法设置可访问性,在类的成员为私有的情况下

设置flat为true将可以通过反射修改成员的值,否则会发生异常

3、Field类

?public Object get(Object o);获取该Field实例对应对象o的Field的值

?public void set(Object obj, Object value) ?;设置该Field对应的对象obj的Field属性的值为value

?

3、Method类

????Class<?>[] getParameterTypes()?;返回该Method的形参类型,按声明顺序

????Class<?> getReturnType()? ?;返回该Method的返回类型

??? Class<?>[] getExceptionTypes()?;返回该Method声明抛出的异常

????Object invoke(Object obj, Object... args)?;执行该Method,obj是该Method所属对象的一个实例

?????????????????????????????????????????????????//args是一个对象数组,表示该Method参数数组实参?
?? 其中args为null或者为空数组时,表示该函数没形参,当obj为null时,表示该函数为静态方法

4、Constructor类

????Class<T> getDeclaringClass();返回该Constructor所表示的Class对象

????Class<?>[] getParameterTypes()?;返回该Constructor表示的形参类型数组

????T newInstance(Object... initargs)?;生成该Constructor表示的对象的一个实例,initargs为形参数组
??

三、例子

??//? 生成Huma实例(带参数)

??? Constructor c=Huma.class.getDeclaredConstructor(new Class[]{String.class,int.class});?

??? Huma huma=c.newInstance(new Object[]{"zhang san",18});

?

?//获取Field,并改变其值

?? Field nameField=Huma.class.getField("zhangsan");

?? nameField.setsetAccessible(true);//注意name属性私有,所以在这里调用,参数为true??

???nameField.set("lisi");//此时name已经变为lisi了,上一句不调用的的话,此句将抛出异常

?

//获取方法并调用

?? Method methodSetName=Huma.class.getMethod("setName",new Class[]{String.class});

?? methodSetName.invoke(huma,new Object[]{"wangwu"});//相当于 huma.setName("wangwu");

?

?最后需要注意的地方就是反射生成的类,修饰符应该是public的,否则,在其他地方调用时可能会出现问题

,例如 在一个 com.abc.Test的main方法中调用 Class.forName("com.knight.Huma"),并且Huma的修饰符不是public时,将抛出异常

热点排行