Java反射技術(個人筆記)

 

首先是最基礎的用法


public class Cat 
{
	String name = "123";
	public Cat()
	{
		System.out.println("null constructor");
	}
	public Cat( String name )
	{
		System.out.println(name);
	}
}

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Constructor;
import java.util.*;

import javax.swing.*;

import org.junit.Test;

public class Main
{

	@Test
	public static void main( String args[] )
	{
		
		try {
			//第①步
			//加載一個類到內存
			Class c = Class.forName("Cat");
		
			//加載類的第二種方式
			Class c2 = new Cat().getClass();
			
			//加載類的第三種方法
			Class c3 = Cat.class;
			
			//第②步
			//通過類獲得構造對象Constructor
			
			//無參數的構造器
			Constructor constructor = c2.getConstructor(null);
			Cat cat = (Cat)constructor.newInstance(null);	//調用Cat中的無參數構造方法
			System.out.println(cat.name);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
	
	
}

 

然後稍微加一點難度(帶參數的構造方法)

package mypackage;

import java.util.Vector;

public class Fish
{
	String name = "red fish";
	public Fish()
	{
		System.out.println("a new fish");
	}
	public Fish( String name )
	{
		System.out.println("a new new fish");
		this.name = name;
	}
	
	private Fish( Vector v )
	{
		System.out.println("a complex constructor");
	}
}

 

package mypackage;

import java.awt.*;
import java.awt.image.*;
import java.lang.reflect.Constructor;
import java.util.Vector;

import javax.swing.*;

import org.junit.Test;


public class Mytest
{
	@Test
	public void test()
	{
	
		try {
			Class c = Class.forName("mypackage.Fish");
			
			//此外,創建對象還有一種方法
			Fish fff = (Fish)c.newInstance();	//但是這種方法只能調用無參數構造方法
			
			Constructor constructor = c.getConstructor(null);
			Fish f = (Fish)constructor.newInstance(null);
			
			
			
			//獲得一個帶參數的構造器
			Constructor constructor2 = c.getConstructor(String.class);	//括號裏應該填類
			Fish f2 = (Fish)constructor2.newInstance("yang");
			System.out.println(f2.name);
			
			//注意,這裏用到的是getDeclaredConstructor,可以得到所有的(包括private),而之前的getconstructor只能得到public
			Constructor constructor3 = c.getDeclaredConstructor(Vector.class);
			
			//暴力反射,(因爲該構造方法是私有的,但是對於反射,依然可以)
			constructor3.setAccessible(true); //寫了這句話就能調用私有的
			//最後創建對象
			Fish f3 = (Fish)constructor3.newInstance(new Vector());
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	}

}

 

然後調用普通的方法

package mypackage;

import java.awt.*;
import java.awt.image.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Vector;

import javax.swing.*;

import org.junit.Test;

//方法的反射
public class Mytest
{
	@Test
	public void test()
	{
	
		try {
			Fish f = new Fish();
			
			Class c = Class.forName("mypackage.Fish");
			
			
			//Fish中normalMethod方法 	public void normalMethod();
			Method method = c.getMethod("normalMethod", null);
			method.invoke(f, null);	//調用
			
			//反射  public String StringMethod(String name)
			method = c.getMethod("StringMethod", String.class);
			method.invoke(f, "這裏填方法的參數");
			
			//反射public int[] ArrayMethod( String name )
			method = c.getMethod("ArrayMethod", String.class);
			int a[] = (int[])method.invoke(f, "string參數");
			System.out.println("a的值 "+a[0]);
			
			//反射  public static void staticMethod( int t )
			method = c.getMethod("staticMethod", int.class);
			method.invoke(null, 123);
			
			//反射public void specialMethod( String s[] )
			method = c.getMethod("specialMethod", String[].class);
			//method.invoke(f, new String[] {"11","22"}); 	//錯誤的寫法,jdk本身的錯誤
			
			method.invoke(f,  (Object) new String[] {"11","22"}  );	//這裏的強制轉換有點特殊
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	}

}

 

package mypackage;

import java.awt.*;
import java.awt.image.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Vector;

import javax.swing.*;

import org.junit.Test;

//方法的反射
public class Mytest
{
	@Test
	public void test()
	{
	
		try {
			Fish f = new Fish();
			
			Class c = Class.forName("mypackage.Fish");
			
			
			Field field = c.getField("name");	//得到字段,
												//如果是私有,就用getDeclaredField,並且加上setAccessible(true);
	
			String s = (String)field.get(f);	//得到一個對象
			System.out.println(s);
			
			//或者下面的寫法
			//下面的寫法更詳細
			
			Object obj = field.get(f);
			Class classType = obj.getClass();
			if( classType.equals(String.class) )
			{
				String value = (String)obj;
				System.out.println("string類");
				
			}
			
			//設置字段的值
			field.set(f, "asd");
			System.out.println(f.name);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	}

}

 

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