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

java反射机制

2016-04-09 09:53 274 查看
纸上得来终觉浅
本来是要学习Spring Aop,无奈Sping Aop<-动态代理<-java反射机制,所以写三篇文章讲述学习历程,这里从java反射机制学起。

首先试着从字面来理解。反射,一种计算机处理方式,是程序可以访问,检测和修改它本身状态或行为的一种能力。

java反射机制主要提供了一下功能,用自己的理解来描述:

1.根据对象找到类

2.根据类找到其中的成员变量和方法

3.以区别于new的形式创建一个对象

4.以区别于“对象.方法”的形式执行方法(这是反射机制在动态代理中的用处,也是反射机制最重要的功能)

示例如下:

/*表示普通人*/
public class Person {
private String name;
private int age;
public Person(){
}
public Person(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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}

/*接口,表示行为*/
public interface Action {
public void walk(int a);
}

public class SuperMan extends Person implements Action{
public void fly(){
System.out.println("SuperMan.fly()");
}
public void walk(int a) {
System.out.println("SuperMan.walk()走了"+a+"米");
}
}


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Main {
public static void main(String[] args) throws ClassNotFoundException,
InstantiationException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException,
NoSuchFieldException,
SecurityException, NoSuchMethodException {
GetFromObject();
}
public static void GetFromObject() throws
ClassNotFoundException,
InstantiationException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException,
NoSuchFieldException,
SecurityException, NoSuchMethodException{

/*一.根据对象得到class*/
/*创建一个Person的对象person*/
Person person = new Person();
/*根据person对象得到它的class,既类的类型*/
Class<?> personClass1 = person.getClass();

/*二.直接根据类名得到class*/
Class<?> personClass2 = Person.class;

/*三.根据包名得到class,三种方式都可以*/
Class<?> personClass3 = Class.forName("com.roadArchitectWeb.reflect.Person");

/*检验三个class*/
/*根据class打印类名和包名*/
System.out.println("打印类名的包名:");
System.out.println("personClass1 类名:"+personClass1.getName()+
" 包名:"+personClass1.getPackage().getName());
System.out.println("personClass2 类名:"+personClass2.getName()+
" 包名:"+personClass2.getPackage().getName());
System.out.println("personClass3 类名:"+personClass3.getName()+
" 包名:"+personClass3.getPackage().getName());

/*下面以personClass1为例,得到其他信息*/
/*1.得到类的构造函数,*/
Constructor<?> constructor[] = personClass1.getConstructors();
for (int i = 0; i < constructor.length; i++) {
System.out.println("Person的构造函数:"+constructor[i].getName()
+" 参数个数:"+constructor[i].getParameterCount());
}
/*2.利用无参构造函数重新实例化person*/
person = (Person)constructor[0].newInstance();
person.setName("majintao1");
person.setAge(1);
System.out.println("利用无参数的构造函数重新实例化person后的结果:"+
person.toString());

/*3.利用带参构造函数重新实例化person*/
person = (Person)constructor[1].newInstance("majintao2",2);
System.out.println("利用带参数的构造函数重新实例化person后的结果:"+
person.toString());

/*4.直接使用类 类型 重新实例化person,同时不使用set和get方法*/
person = (Person) personClass1.newInstance();/*这里只能使用无参的构造函数,newInstance无参数*/
//			person.setName("majintao3");
//			person.setAge(3);
/*操作set和get*/
Field personNameField = personClass1.getDeclaredField("name");
/*name类型为privae,设置access才能访问*/
personNameField.setAccessible(true);
personNameField.set(person, "majintao4");
Field personAgeField = personClass1.getDeclaredField("age");
/*age类型为privae,设置access才能访问*/
personAgeField.setAccessible(true);
personAgeField.set(person, 4);
System.out.println("利用类类型重新实例化person后的结果:"+
person.toString());

/*得到类成员和类方法*/
Field fields[] = personClass1.getDeclaredFields();
for (int i= 0;  i< fields.length; i++) {
System.out.println("类中的成员: " + fields[i]);
}
Method methods[] = personClass1.getMethods();
System.out.println("函数名:" + methods[1].getName());
System.out.println("函数返回类型:" + methods[1].getReturnType());
System.out.println("函数访问修饰符:" + Modifier.toString(methods[1].getModifiers()));
System.out.println("函数代码写法: " + methods[1]);

/*得到接口信息*/
Class<?> superManClass1 = Class.forName("com.roadArchitectWeb.reflect.SuperMan");
Class<?> interfaces[] = superManClass1.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
System.out.println("实现的接口类名: " + interfaces[i].getName() );
}

/*调用类中的方法,这个就是动态代理需要用到的,也是反射机制最重要部分*/
System.out.println("调用无参方法fly():");
Method method = superManClass1.getMethod("fly");
method.invoke(superManClass1.newInstance());
System.out.println("调用有参方法walk(int a):");
method = superManClass1.getMethod("walk",int.class);
method.invoke(superManClass1.newInstance(),100);

/*获得类加载器信息*/
/*superManClass1.getSuperclass()相当于personClass1*/
String personString = superManClass1.getSuperclass().getClassLoader().getClass().getName();
String superString = superManClass1.getClassLoader().getClass().getName();
System.out.println("personString:"+personString);
System.out.println("superString:"+superString);
}
}
结果如下:

打印类名的包名:
personClass1 类名:com.roadArchitectWeb.reflect.Person 包名:com.roadArchitectWeb.reflect
personClass2 类名:com.roadArchitectWeb.reflect.Person 包名:com.roadArchitectWeb.reflect
personClass3 类名:com.roadArchitectWeb.reflect.Person 包名:com.roadArchitectWeb.reflect
Person的构造函数:com.roadArchitectWeb.reflect.Person 参数个数:0
Person的构造函数:com.roadArchitectWeb.reflect.Person 参数个数:2
利用无参数的构造函数重新实例化person后的结果:Person [name=majintao1, age=1]
利用带参数的构造函数重新实例化person后的结果:Person [name=majintao2, age=2]
利用类类型重新实例化person后的结果:Person [name=majintao4, age=4]
类中的成员: private java.lang.String com.roadArchitectWeb.reflect.Person.name
类中的成员: private int com.roadArchitectWeb.reflect.Person.age
函数名:getName
函数返回类型:class java.lang.String
函数访问修饰符:public
函数代码写法: public java.lang.String com.roadArchitectWeb.reflect.Person.getName()
实现的接口类名: com.roadArchitectWeb.reflect.Action
调用无参方法fly():
SuperMan.fly()
调用有参方法walk(int a):
SuperMan.walk()走了100米
personString:sun.misc.Launcher$AppClassLoader
superString:sun.misc.Launcher$AppClassLoader


上段代码详细用到了开始处提到的四个功能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息