閱讀719 返回首頁    go 阿裏雲 go 技術社區[雲棲]


JAVA反射機製

一、JAVA反射機製的概念:

         在程序運行時,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取信息以及動態調用對象的方法的功能稱為java語言的反射機製。

二、功能:

  在程序運行時判斷任意一個對象所屬的類;在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變量和方法;在運行時調用任意一個對象的方法;生成動態代理。

三、API使用示例

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

/**
 * 反射學習筆記
 */
public class ReflectDemo {

	public static void main(String[] args) {
		try {
			//獲得Class對象的三種方式
			//方式一:
			Class class1 = int.class;	//8個基本數據類型和一個特殊類型void獲取Class對象的方式
			class1 = Cat.class;
			//包裝類的獲取方式
			class1 = Integer.class;
			class1 = Integer.TYPE;
			
			//方式二:
			//引用類型
			class1 = "abc".getClass();	
			class1 = new String().getClass();
			class1 = new Cat().getClass();
			
			//方式三:
			class1 = Class.forName("java.lang.String");
			
			//基本類型和包裝類型的Class對象
			Class<Boolean> booleanClass = boolean.class;
			Class<Boolean> booleanClass2 = Boolean.TYPE;
			//比較的是內存中的字節碼文件,而非字節碼文件中的內容
			System.out.println("boolean.class==Boolean.TYPE: " + (booleanClass == booleanClass2));
			Class<Byte> byteClass = byte.class;
			Class<Byte> byteClass2 = Byte.TYPE;
			System.out.println("byte.class==Byte.TYPE: " + (byteClass == byteClass2));
			Class<Character> charClass = char.class;
			Class<Character> charClass2 = Character.TYPE;
			System.out.println("char.class==Character.TYPE: " + (charClass == charClass2));
			Class<Short> shortClass = short.class;
			Class<Short> shortClass2 = Short.TYPE;
			System.out.println("short.class==Short.TYPE: " + (shortClass == shortClass2));
			Class<Integer> integerClass = Integer.TYPE;
			Class<Integer> intClass = int.class;
			System.out.println("int.class==Integer.TYPE: " + (intClass == integerClass));
			Class<Long> longClass = long.class;
			Class<Long> longClass2 = Long.TYPE;
			System.out.println("long.class==Long.TYPE: " + (longClass == longClass2));
			Class<Float> floatClass = float.class;
			Class<Float> floatClass2 = Float.TYPE;
			System.out.println("float.class==Float.TYPE: " + (floatClass == floatClass2));
			Class<Double> doubleClass = double.class;
			Class<Double> doubleClass2 = Double.TYPE;
			System.out.println("double.class==Double.TYPE: " + (doubleClass == doubleClass2));
			Class<Void> voidClass = void.class;
			Class<Void> voidClass2 = Void.TYPE;
			System.out.println("void.class==Void.TYPE: " + (voidClass == voidClass2));
			System.out.println("int[][].class == int[][].class: " + (int[][].class == int[][].class));
			//判斷數據類型
			System.out.println("int.class.isPrimitive(): " + int.class.isPrimitive());	//判斷是否基本數據類型
			System.out.println("Integer.class.isPrimitive(): " + Integer.class.isPrimitive());
			System.out.println("int[].class.isPrimitive(): " + int[].class.isPrimitive());
			System.out.println("int[].class.isArray(): " + int[].class.isArray());		//判斷是否數組類型
			
			System.out.println("---------------------------------------");
			Class<Cat> classz = Cat.class;
			// 調用無參的公共構造方法
			Constructor<Cat> constructor = classz.getConstructor(null);
			Cat cat = constructor.newInstance(null);

			// 調用帶參數的公有構造方法
			constructor = classz.getConstructor(String.class);
			cat = constructor.newInstance("湯姆貓");
			System.out.println(cat.getName());
			
			//調用帶參的私有構造方法
			constructor = classz.getDeclaredConstructor(String.class,String.class);
			constructor.setAccessible(true);
			cat = constructor.newInstance("不吃老鼠的貓","黃貓");
			
			//獲得一個屬性的值(公共的)
			Field fieldName = classz.getField("name");
			System.out.println(fieldName.get(cat));
			fieldName.set(cat, "美貓貓");
			System.out.println(fieldName.get(cat));
			//私有的
			fieldName = classz.getDeclaredField("type");
			fieldName.setAccessible(true);
			fieldName.set(cat,"挪威森林貓");
			System.out.println(fieldName.get(cat));
			
			//調用無參的公共方法
			Method method = classz.getMethod("catchMouse", null);
			method.invoke(cat, null);
			//調用帶參的公共方法
			method = classz.getMethod("eat", String.class);
			method.invoke(cat, "魚");
			//調用私有方法
			method = classz.getDeclaredMethod("display", null);
			method.setAccessible(true);
			method.invoke(cat, null);
			
			//調用帶數組參數的方法
			Class arraysClass = Class.forName("java.util.Arrays");	//加載內存中java.util.Arrays的Class字節碼文件
			Method arrayMethod = arraysClass.getMethod("sort", int[].class);
			int[] nums = {3,5,9,2,6,10};
			arrayMethod.invoke(null, nums);	//因為sort是java.util.Arrays類的靜態方法,不需要實例對象,所以第一個參數為null
			arrayMethod = arraysClass.getMethod("toString", int[].class);
			System.out.println(arrayMethod.invoke(null, nums));	//打印排序後的數組
			
			//獲得父類信息
			System.out.println(classz.getSuperclass().getName());	//獲得父類的名稱
			Class superClass = classz.getSuperclass();
			Method[] methods = superClass.getDeclaredMethods();	//獲得父類的所有方法,包括私有方法
			for (Method method2 : methods) {
				System.out.print(method2.getName() + " ");
			}
			System.out.println();
			//判斷是否抽象類,用java.lang.reflect.Modifier類可以獲得一個類中成員的訪問修飾符
			int modifier = superClass.getModifiers();
			System.out.println(Modifier.isAbstract(modifier));
			
			//獲得父類的所有屬性,包括私有的
			Field[] fields = superClass.getDeclaredFields();
			for (Field field : fields) {
				System.out.print(field + "  ");
			}
			System.out.println();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

/**
 * 動物
 */
abstract class Animal {

	/**
	 * 名稱
	 */
	public String name;

	/**
	 * 顏色
	 */
	private String color;

	/**
	 * 年齡
	 */
	private int age;

	public int getAge() {
		return age;
	}

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

	public String getName() {
		return name;
	}

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

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	/**
	 * 吃東西
	 * 
	 * @param name
	 */
	public abstract void eat(String name);

}

/**
 * 貓
 * 
 */
class Cat extends Animal {

	/**
	 * 貓的種類
	 */
	private String type;

	public Cat() {
		System.out.println("Cat");
	}
	
	private Cat(String name,String type) {
		this.name = name;
		this.type = type;
	}

	public Cat(String name) {
		this.name = name;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	/**
	 * 抓老鼠
	 */
	public void catchMouse() {
		System.out.println("抓老鼠。。。");
	}

	@Override
	public void eat(String foodName) {
		System.out.println("貓吃" + foodName + "。");
	}
	
	/**
	 * 顯示貓的名稱
	 */
	private void display() {
		System.out.println("name:" + name);
	}

}

最後更新:2017-04-02 06:52:22

  上一篇:go Oracle SQL經典薈萃
  下一篇:go Andriod Activity和Service同一線程的情況和不在同一線程的情況