Java反射机制详解

       Java反射机制是在运行状态中,对于任意一个类(Class文件),都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

     三种创建方式:1、利用Object类中的getClass方法。

public static void getClassObject_1(){
    	Person p = new Person();
    	Class clazz = p.getClass();
    	
    	Person p1 = new Person();
    	Class clazz1 = p1.getClass();
    	
    	System.out.println(clazz == clazz1);
    }

                          2、利用类的静态属性 .class

private static void getClassObject_2() {
		
    	Class clazz = Person.class;
    	Class clazz1 = Person.class;
    	
    	System.out.println(clazz == clazz1);
	} 

                      3、通过给定类的字符串名称获取该类。

  private static void getClassObject_3() throws ClassNotFoundException {

    	String className = "cn.bjtu.jlj.model.Person";
    	Class clazz = Class.forName(className);
    	
    	System.out.println(clazz);
	}

             第一种方式必须要明确具体的类,并创建对象。第二种方式仍需要用到类中的静态成员,明确具体的类。第三种方式只要有名称即可,更为方便,扩展性更强,在开发中更常用到。
          

         利用反射生成类的对象:

     可以利用Class 的 newInstance() 方法创建此 Class 对象所表示的类的一个新实例。如同用一个带有一个空参数列表的new 表达式实例化该类。如果该类尚未初始化,则初始化这个类。对于带有参数的构造函数,调用Class类的getConstructor(Class<?>...parameterTypes)方法,它返回一个Constructor对象,调用这个对象的newInstance()方法。

public static void creatNewObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
	   String name = "cn.bjtu.jlj.model.Person";
	   Class clazz = Class.forName(name);
	   Object obj = clazz.newInstance();
   }

public static void creatNewObject_2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
	   String name = "cn.bjtu.jlj.model.Person";
	   Class clazz = Class.forName(name);
	   Constructor ct = clazz.getConstructor(String.class,int.class);
	   Object obj = ct.newInstance("小明",39);
}


怎样得到反射类中的属性,常用的方法:

getFields() :返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。

getField(String name):返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。

getDeclareFields(): 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。

getDeclareField(Stirng name):返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。

前两个方法只能得到这个类的公有域,利用下面两个方法可以得到所有字段,包括私有。但默认不可对私有域进行访问或其他操作。调用其父类AccseeibleObject的setAccessible(boolean flag)方法,将此对象的 accessible 标志设置为指示的布尔值,值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。 将flag设置为true,则可以对私有域进行操作。利用get()和set()方法读取和设置类的属性,因为它是与对象相关联的,所以应将要操作的对象作为参数传进去。

public static void getFieldDemo() throws Exception {

		 String name = "cn.bjtu.jlj.model.Person";
		   Class clazz = Class.forName(name);
		   Constructor ct = clazz.getConstructor(String.class,int.class);
		   Object obj = ct.newInstance("小明",39);
		   
		   Field[] fieldall = clazz.getFields();
		   
		   Field fieldname = clazz.getField("name");
		   System.out.println(fieldname.get(obj));
		   Field fieldage = clazz.getDeclaredField("age");
		  
		   fieldage.setAccessible(true);
		   
		   System.out.println(fieldage.get(obj));
		   
		   fieldage.set(obj, 89);
		   Object o = fieldage.get(obj);
		   
		   System.out.println(o);
	}

利用getMethods()和getDeclareMethods()获得类中的方法:

public static void getMethodDemo() throws Exception {

		Class clazz = Class.forName("cn.bjtu.jlj.model.Person");
		
		Method[] methods = clazz.getMethods();//获取的是所有公用的方法,包括继承父类的。
		for(Method aaa:methods){
			System.out.println(aaa);
		}

运行结果:

public void cn.bjtu.jlj.model.Person.method()
public void cn.bjtu.jlj.model.Person.paramMehtod(java.lang.String,int)
public void cn.bjtu.jlj.model.Person.show()
public static void cn.bjtu.jlj.model.Person.staticMethod()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()


public static void getMethodDemo() throws Exception {

		Class clazz = Class.forName("cn.bjtu.jlj.model.Person");
		
		Method[] methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包含私有。
		for(Method aaa:methods){
			System.out.println(aaa);
		}
	}

运行结果:

public void cn.bjtu.jlj.model.Person.method()
public void cn.bjtu.jlj.model.Person.paramMehtod(java.lang.String,int)
public void cn.bjtu.jlj.model.Person.show()
public static void cn.bjtu.jlj.model.Person.staticMethod()


调用getMethod("方法名",参数,...)获得与传入相同方法名名字相同的方法。执行该方法则调用返回方法对象的invoke(object,参数,...)方法,object即你要操作的对象。

获取并执行无参方法:

public static void getMethodDemo_2() throws Exception {

		Class clazz = Class.forName("cn.bjtu.jlj.model.Person");
		Method method = clazz.getMethod("show", null);
		Constructor ct = clazz.getConstructor(String.class,int.class);
		Object obj = ct.newInstance("小明",39);
		method.invoke(obj, null);
	}


获取并执行有参方法:

public static void getMethodDemo_3() throws Exception {

		Class clazz = Class.forName("cn.bjtu.jlj.model.Person");
		Method method = clazz.getMethod("paramMehtod", String.class,int.class);
		Object obj = clazz.newInstance();
		method.invoke(obj, "小明",39);
	}







       



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值