最近在看个Spring框架,其中有一个章节讲述的AOP编程,使用代理实现的。我就搜了下java中代理的东西,发现java中的代理是用java中的反射实现的。所有我就查看了一下java中反射的知识,做了一下学习笔记,就当做以后查阅的资料吧!代码如下。
Person类的代码如下:
package com.test;
public class Person {
public int id;
public String name;
private int age;
public Person(){
Log("default constructor");
}
public Person(int id,String name){
Log("two parameters constructor");
this.id=id;
this.name=name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
public int getId(){
return id;
}
public void p(int age,String name){
System.out.println("age:"+age+" name:"+name);
}
private void p2(int age,String name,int id){
System.out.println("age:"+age+" name:"+name+" age:"+id);
}
public void p3(int id,String name){
System.out.println("id:"+id+" name:"+name);
}
private void Log(String msg){
System.out.println("Person:"+msg);
}
}
测试反射的代码如下
package com.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectTest {
public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchFieldException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
System.out.println("获得Class对象");
/*
* 三种获得Class对象的方法
* 1、Class.forName
* 2、.class
* 3.getClass
*/
Person p = new Person();
//1、Class.forName获得Class对象
Class<?> p1 = Class.forName("com.test.Person");
//2、.class获得Class对象
Class<?> p2 = Person.class;
//3、getClass获得Class对象
Class<?> p3 = p.getClass();
System.out.println("p1:"+p1);
System.out.println("p2:"+p2);
System.out.println("p3:"+p3);
System.out.println("获得Field");
/*
* 获得类fields的集中方法
* 1、getField
* 2、getFields
* 3、getDeclaredField
* 4、getDeclaredFields
* 其中有Declare和没有Declared的区别在于能否读出私有的成员,有Declare的能够读出私有的成员,(如果有继承关系的话
* getField还可以读出父类的成员,这个没有试过,但是看过了这个用法)
*/
//1、getField,其中参数为field的名称
Field f1 = Person.class.getField("id");
System.out.println("f1:"+f1);
//2、getFields 返回所有的field值
Field[] f2 = Person.class.getFields();
for(Field f :f2){
System.out.println("f2:"+f);
}
//3、getDeclareField
Field f3 = Person.class.getDeclaredField("age");
System.out.println("f3:"+f3);
//4、getDeclareFields
Field[] f4 = Person.class.getDeclaredFields();
for(Field f:f4){
System.out.println("f4:"+f);
}
System.out.println("获得Method");
/*
* 也有四种读取Method的方法
* 1、getMethods
* 2、getMethod(方法名,参数列表)
* 3、getDeclaredMethods
* 4.getDeclaredMethod(方法名,参数列表)
* 有和没有Declared与之前的一样
*/
Method[] m1 =Person.class.getMethods();
for(Method m:m1){
System.out.println("m1:"+m1);
}
Method m2 = Person.class.getMethod("p", int.class,String.class);
System.out.println("m2:"+m2);
Method[] m3 =Person.class.getDeclaredMethods();
for(Method m:m3){
System.out.println("m3:"+m3);
}
Method m4 = Person.class.getDeclaredMethod("p2", int.class,String.class,int.class);
System.out.println("m4:"+m4);
System.out.println("获取Constructor");
/*
* 也有四种获得constructor 的方法
* 1、getConstructor(参数列表)
* 2、getConstructors
* 3、getDeclaredConstructor(参数列表)
* 4、getDeclaredConstructors
*/
Constructor c1 = Person.class.getConstructor(int.class,String.class);
System.out.println("c1:"+c1);
Constructor[] c2 = Person.class.getConstructors();
for(Constructor c :c2){
System.out.println("c2:"+c);
}
Constructor c3 = Person.class.getDeclaredConstructor(int.class,String.class);
System.out.println("c3:"+c3);
Constructor[] c4 = Person.class.getDeclaredConstructors();
for(Constructor c:c4){
System.out.println("c4:"+c);
}
System.out.println("创建一个新的实例");
/*
* 创建类的实例
* 1、无参数的
* 2、有参数的
* 其中无参数的又有两种
*/
Object o1 = Person.class.newInstance();
System.out.println("o1:"+o1);
Constructor c = Person.class.getConstructor();
Object o2 = c.newInstance();
System.out.println("o2:"+o2);
Constructor tempc = Person.class.getConstructor(int.class,String.class);
Person tempp = (Person) tempc.newInstance(24,"张三");
System.out.println(tempp.id);
System.out.println("方法的调用");
/*
* 调用类的函数
*/
Method tempm = Person.class.getMethod("p3", int.class,String.class);
tempm.invoke(tempp, 11,"haha");
//如果要调用私有方法,则必须改变其访问性
Method tm = Person.class.getDeclaredMethod("p2", int.class,String.class,int.class);
//如果不加下面这一行会报错
tm.setAccessible(true);
tm.invoke(tempp, 1,"a",2);
System.out.println("访问域");
Field tf = Person.class.getField("id");
tf.setInt(tempp, 0);
System.out.println("id:"+tempp.getId());
//如果访问私有域
Field tf2 = Person.class.getDeclaredField("age");
//如果要访问私有域,则必须加上下面这一行
tf2.setAccessible(true);
tf2.setInt(tempp, 100);
System.out.println("age:"+tempp.getAge());
}
}