黑馬程序員_java反射


---------------------- android培訓java培訓、期待與您交流! ----------------------

 

反射就是把JAVA類中的各種成分映射成相應的java類。

反射主要可以完成三種功能:實例化對象 、 獲取類的信息 和 操作類中的方法和屬性。

  實例化對象:

   以前咱們使用  “類名 obj = new 類名()” 來實例化一個對象。

  現在咱們使用  其他方式 來實例化一個對象。

  獲取類信息:

 通過Class對象來獲取(映射)出該類的一些信息。

     比如獲取類中的方法、屬性等信息。

  操作類中的方法和屬性:

   通過反射來調用和修改屬性和方法。

使用反射的範例:

    開發工具都有隨筆提示功能  這就是通過反射來做到的。

 

Class類

在反射機制中Class類是一個操作的源頭,所有的反射操作都通過這個類來完成。

一個Class類的對象 就代表一個類。

在Java中有三種方法可以實例化Class類的對象:

  通過Object類的“對象.getClass()”方法。

 通過“類.class”的方式。

 通過“Class.forName()”來實例化Class類對象。

範例1: 通過“對象.getClass()”實例化Class類。

package org.hwh.demo;

public class ClassDemo {

    public static void main(String[] args){

       Person p = new Person("張三",50);

       Class<?> cls = p.getClass();

       System.out.println(cls.getName());

    }

}

  Class類的getName()方法  返回該Class對象所表示的類的類名。

 

範例2: 通過“類.class”實例化Class類。

package org.hwh.demo;

public class ClassDemo {

    public static void main(String[] args){

       Class<?> cls = Person.class;  //返回一個Class<Person>類型的對象。 

       System.out.println(cls.getName());

    }

}

  Class<?> 代表 可以接受任意Class<T>類型的對象。

 

範例3: 通過“Class.forName()”實例化Class類。

package org.hwh.demo;

public class ClassDemo1 {

    public static void main(String[] args) throws Exception {

       Class<?> cls = Class.forName("org.hwh.demo.Person"); 

       System.out.println(cls.getName());

    }

}

  此時需要指明類的完整名稱:“包名.類名稱”。 此方式最常用。 但是會拋出異常。

 

通過Class類實例化對象:

在Class的使用中實例化對象是最常用的一種操作,而且在日後所有的框架、各個程序的實現原理都是依靠Class類來完成的。

 

範例1: 實例化Person類對象。

package org.hwh.demo;

public class ClassDemo {

    public static void main(String[] args) throws Exception {

       Class<?> cls = Class.forName("org.hwh.demo.Person"); 

//調用Person類的無參構造方法,實例化對象。

       Person p = (Person)cls.newInstance();

       System.out.println(p);

    }

}

  如果Person類中沒有無參的構造方法 則運行的時候會拋異常。

 

範例2: 調用指定構造方法 實例化Person類對象。

package org.hwh.demo;

import java.lang.reflect.Constructor;

public class ClassDemo {

    public static void main(String[] args) throws Exception {

       Class<?> cls = Class.forName("org.hwh.demo.Person"); 

        // 返回Person類中的所有構造方法

       Constructor<?>[] con = cls.getConstructors();

        // 使用指定的構造方法  實例化一個對象

       Person p = (Person)con[1].newInstance("張三",55);

       System.out.println(p);

    }

}

語句解釋:

先使用foreach遍歷這個構造方法數組 然後根據顯示的結果 在決定調用哪一個構造方法。

使用範例2實例化對象很麻煩。

因此爲了反射的方便:以後應該爲每一個類定義一個無參的構造方法。

 

關於反射的小應用:

1.得到一個類的所有構造方法

package demo;

import java.lang.reflect.Constructor;

public class Demo {
	
	public static void main(String[] args)throws Exception {
		Class<?> clazz=Class.forName("java.lang.String");
		Constructor[] constructors=clazz.getConstructors();
		for(Constructor constructor:constructors)
			System.out.println(constructor);
	}

}

2.得到一個類的字段,並且把該字段值中的"a"改成"b"

package field;

public class Student {
	private String str1="aaaaaaa";
	public String toString()
	{
		return str1;
	}
}


 

package field;

import java.lang.reflect.Field;

public class MyField {

	/**
	 * @param args
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws  
	 */
	public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException  {
		Student stu=new Student();
		Field[] fields=stu.getClass().getDeclaredFields();
		for( Field field:fields)
		{
			if(field.getType()==String.class)
			{
				field.setAccessible(true);
				String old=(String)field.get(stu);
				String nw=old.replace('a', 'b');
				field.set(stu, nw);
			}
		}
		System.out.println(stu);
	}

}


3.得到一個類中的所有方法

package demo;

import java.lang.reflect.Method;

public class Demo {
	
	public static void main(String[] args)throws Exception {
		Class<?> clazz=Class.forName("java.lang.String");
		Method[] methods=clazz.getMethods();
		for(Method method:methods)
			System.out.println(method.getName());
	}

}


反射將來會很有用處,如開發框架等。

 

---------------------- android培訓java培訓、期待與您交流!

---------------------- 詳細請查看:http://edu.csdn.net/heima

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章