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

java反射机制详解及应用

2016-06-06 16:26 513 查看
1.如何创建Class的实例(反射的源头)

理解:
Class是一个对象,对应一个运行时类。相当于一个运行时类本身充当了Class的一个实例

过程:
源文件经过编译(javac.exe)这步,就需要进行类的加载(通过JVM的类的加载器)
记载到内存中的缓存,每一个放入缓存中的.class文件就是一个Class实例!
Java.lang.Class是反射的源头。
接下来涉及到的类都在java.lang.reflect子包下
如:Field MethodConstructor Type Package
通过Class实例调用getMethods获取所有的方法,getContructors()获取所有的Constructor
实例化Class的方法
1.调用运行时类的.class属性如:Class
clazz1=Person.class; ;
2.调用类的对象,调用其getClass方法
如:Person p=new Person(); Classclazz2=p.getClass();
3.调用Class静态方法forName(String
className)此方法报ClassNotFoundException如:; Class
clazz3=Class.forName("1.txt");
4.通过类的加载器:ClassLoaderloader=this.getClass().getClassLoader(); Class
clazz4=loader.loadClass("1.txt");

 
2.有了Class实例之后可以做什么:(见demo)
2.1可以创建对应的运行时类的对象
2.2可以获取对应的运行时类的完整的类的结构:属性、方法、构造器、包、父类、接口、泛型、注解、异常、内部类。。。如:
Method[] m1=clazz,getMethods()获取对应的运行时类(声明的Public方法),(包含父类的)
Method[] m2=clazz.getDeclaredMethod()获取对应的运行时类本身的所有公有或私有的方法(不包含父类)(任何权限)
2.3可以调用运行时类中指定的结构(某个指定的属性、方法、构造器)(见demo)
3.动态代理--反射的应用,体会反射的动态性  
package myNetDemo;

import javax.print.attribute.standard.Sides;

public class Animal {
private String name;
public int age;
static String desc="我是一个小动物";
public Animal(){
super();
System.out.println("测试clazz.instance()调用的初始构造器是这个!");
}

//test怎样调用private构造器,利用反射
private Animal(String name,int age){
super();
this.name=name;
this.age=age;
}

@Override
public String toString() {
return "Animal [name=" + name + ", age=" + age +  "]";
}

public static void info(){
System.out.println("动物");
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

//为了测试调用私有方法的方法
private int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public static String getDesc() {
return desc;
}

public static void setDesc(String desc) {
Animal.desc = desc;
}

public void show(String desc){
System.out.println("我是一个,"+desc);
}

}

package myNetDemo;

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

import org.junit.Test;

public class TestReflection {
// 调用指定的方法
@Test
public void test4() throws Exception {
Class clazz = Class.forName("myNetDemo.Animal");
Object obj = clazz.newInstance();
Animal a = (Animal) obj;

// 调用private方法
Method m1 = clazz.getDeclaredMethod("getAge");
m1.setAccessible(true);
int age = (int) m1.invoke(a);// 方法的返回值是getAge()的返回值
System.out.println(age);
// 调用public方法
Method m2 = clazz.getMethod("show", String.class);
Object returnVal = m2.invoke(a, "小花猫");
System.out.println(returnVal);//show方法的返回值,若void则为null
// 调用静态方法static
Method m3=clazz.getDeclaredMethod("info");
m3.setAccessible(true);
m3.invoke(a);
m3.invoke(Animal.class);
m3.invoke(null);
}

// 调用指定的属性
@Test
public void test3() throws Exception {
Class clazz = Class.forName("myNetDemo.Animal");
Object obj = clazz.newInstance();
Animal a = (Animal) obj;

// 调用私有属性
Field f1 = clazz.getDeclaredField("name");
f1.setAccessible(true);
f1.set(a, "Jerry");

// 调用共有的属性
Field f2 = clazz.getField("age");
f2.set(a, 9);
System.out.println(a);
// 要获取某个属性,是获取对象的属性
System.out.println(f2.get(a));

// 调用静态的属性
Field f3 = clazz.getDeclaredField("desc");
System.out.println(f3.get(Animal.class));
System.out.println(f3.get(a));
System.out.println(f3.get(null));

}

// 调用指定构造器调用运行时对象
@Test
public void test2() throws Exception {
Class clazz = Animal.class;

Constructor c = clazz.getDeclaredConstructor(String.class, int.class);// 调用私有方法
c.setAccessible(true);// 设置访问权限
Animal a = (Animal) c.newInstance("Tom", 10);
System.out.println(a);
}

// 获取运行时对象,方式一
@Test
public void test1() throws Exception {
Class clazz = Class.forName("myNetDemo.Animal");
Object obj = clazz.newInstance();// 创建运行时对象,默认调用的是空参构造器
Animal a = (Animal) obj;
System.out.println(a);
}

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