java反射

通过一个对象获得完整的包名和类名

package reflect;

public class GetClass {
	public static void main(String[] args) {
		GetClass c=new GetClass();
		System.out.println(c.getClass().getName());
		System.out.println("结果是reflect.GetClass");
		Demo d=new Demo();
		System.out.println(d.getClass().getName());
		System.out.println("结果是reflect.Demo");
	}
}
class Demo{
	
}

 

所有类的对象其实都是Class的实例。

 实例化class对象

package reflect;

public class GetClass {
	public static void main(String[] args) {
		Class<?> demo1=null;
        Class<?> demo2=null;
        Class<?> demo3=null;
        demo1=Demo.class;
        demo2=new Demo().getClass();
        try {
			demo3=Class.forName("reflect.Demo");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
        System.out.println("demo1,2,3的值是class reflect.Demo");
        System.out.println("类名称   "+demo1.getName());
        System.out.println("类名称   "+demo2.getName());
        System.out.println("类名称   "+demo3.getName());
        System.out.println("他们的值都是reflect.Demo");
	}
}
class Demo{
	
}

  

通过一个类获取其所有的属性

 

package reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class hello {
	public static void main(String[] args) {
		/*获取本类的全部属性*/
		  Class<?> demo = null;
		 /* try {
			demo=Class.forName("reflect.Demo");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} */
		 // demo=Demo.class;
		  demo=new Demo().getClass();
		  //获取某个类所声明的字x段(包括public、private、protected)
		  Field[] field=demo.getDeclaredFields();
		  for(int i=0;i<field.length;i++){
			  //返回修饰符的编码
			  int mo=field[i].getModifiers();
			  //获取修饰符名称
			  String decorate=Modifier.toString(mo);
			  //输出修饰符名称
			  System.out.println(decorate);
			  //获取属性类型
			  Class<?> type=field[i].getType();
			  //输出属性类型
			  System.out.println(type);
			  //获取属性名称
			  System.out.println(field[i].getName());
			  
			  //如果要获取其自身的属性和其父类或者接口的属性,用
			  //Field[] field=demo.getFields();这个方法
		  }
	}
}
class Demo{
	public String name;
	public String age;
	private int id;
	
}

 输出结果是

public
class java.lang.String
name
public
class java.lang.String
age
private
int
id

通过class调用其他类中的构造函数

package Reflect;
 
import java.lang.reflect.Constructor;
 
class Person{
     
    public Person() {
         
    }
    public Person(String name){
        this.name=name;
    }
    public Person(int age){
        this.age=age;
    }
    public Person(String name, int age) {
        this.age=age;
        this.name=name;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    @Override
    public String toString(){
        return "["+this.name+"  "+this.age+"]";
    }
    private String name;
    private int age;
}
 
class hello{
    public static void main(String[] args) {
        Class<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch (Exception e) {
            e.printStackTrace();
        }
        Person per1=null;
        Person per2=null;
        Person per3=null;
        Person per4=null;
        //取得全部的构造函数
        Constructor<?> cons[]=demo.getConstructors();
        try{
            per1=(Person)cons[0].newInstance();
            per2=(Person)cons[1].newInstance("Rollen");
            per3=(Person)cons[2].newInstance(20);
            per4=(Person)cons[3].newInstance("Rollen",20);
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println(per1);
        System.out.println(per2);
        System.out.println(per3);
        System.out.println(per4);
    }
}

【运行结果】:

[null  0]

[Rollen  0]

[null  20]

[Rollen  20]

 

 

关于反射中invoke方法的使用

method.invoke(Object obj, Object args[])

obj是个对象,必须是实例化的对象。args是个用于方法调用的参数,是Object数组,因为参数可能有多个。

Method类代表一个方法,所以invoke(调用)就是调用Method类代表的方法。它可以让你实现动态调用,例如你可以动态的传入参数。

package reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
	public static void main(String[] args) {
		String [] names ={"tom","tim","allen","alice"};
		Class<?> clazz=hi.class;
		Method method = null;
		try {
			method=clazz.getMethod("sayHi", String.class);
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		for(String name:names){
			try {
				method.invoke(clazz.newInstance(), name);
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}

}
class hi{
	public void sayHi(String name){
		System.out.println("hi,"+name);
	}
}

 

结果 

hi,tom
hi,tim
hi,allen
hi,alice

 getDeclaredMethod

public Method getDeclaredMethod(String name, Class... parameterTypes) throws NoSuchMethodException, SecurityException

java.lang.Class.getDeclaredMethod()方法返回一个Method对象,它反映此Class对象所表示的类或接口的指定已声明方法。name参数是一个字符串,指定所需的方法的简单名称,parameterTypes参数是一个数组的Class对象识别方法的形参类型,在声明的顺序

例如

Method realMethod = serviceProcessor.getClass().getDeclaredMethod(methodName,JSONObject.class);
			
			JSONObject paramJson =  (JSONObject) JSONObject.parse(param);
			
			String data = ((String) realMethod.invoke(serviceProcessor, paramJson));

 .class和.getClass的区别

出现的时期不同:Class.forName()在运行时加载;Class.class和getClass()是在编译器加载,即.class是静态加载,.getClass()是动态加载。

.getClass()是一个对象实例的方法,只有对象实例才有这个方法,具体的类是没有的。类的Class类实例是通过.class获得的,显然,类没有.getClass()方法。 

如:

protected  Logger log=Logger.getLogger(this.getClass());
protected static final Logger log=Logger.getLogger(HttpUtil.class);

 注意this是当前类的实例,static表示是静态的 

posted @ 2016-06-14 20:40  Lost blog  阅读(275)  评论(0)    收藏  举报