1. 程式人生 > >Java反射(reflection)特點

Java反射(reflection)特點

*.class檔案介紹

學習Java的初學者都知道Java中存在JVM來包裝java語言使得java在各種機器上都能很好的執行。一個*.java的檔案首先編譯成*.class檔案,*.class檔案是JVM能夠識別的檔案,最後*.class檔案在JVM下編譯成機器可以識別的二進位制檔案。


Class類引入

正是在*.class檔案的基礎上才引來了reflection機制。java中reflection機制就是供程式設計師來讀取*.class檔案中的有用的資訊。首先java提供了一個Class(public final class Class<T> //是一個公共常量類)正是利用Class類物件來指定呼叫的*.class的·檔名進而利用這個Class類物件來操作*.class中的Field、Method、ParameterType等取得各種引數。

以下簡述如何利用Class尋找指定Method並呼叫goalMethod

//建立

  1. Class cls=String.class;
  2. String str="中國你好";    Class cls=str.getClass();
  3.    Class cls=class.forName("Test5.Hello");   //直接查詢路徑

//列出Method、Field

Method[ ] methods=cls.getMethods( );

Field[ ] fields=cls.getFields( );

for(Method m : methods)

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

for(Field f : fields)

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

 

//例項化Class

Object obj=cls.newInstance( );

 

//利用MethodName、Paramer取得指定Method

String methodName="setIInformation";

Class[ ] parameterType={int.class,String.class};

Method mGoal=cls.getMethod(methodName,parameterType);  //找到指定Method

Object[ ] parameter={123,"shenchong"};   //引數賦值

mGoal.invoke(obj,parameter);  //利用invoke函式呼叫指定method


實戰專案

利用File、properties、Class技術配置控制檯login命令響應。

   說明:專案實現在eclipse下的Console視窗下輸入login usename=shenchong password=123456實現將usename、password的值傳給響應類中的setter中,其中login是程式取得輸入的命令。程式碼和執行結果如下:

//ScShell.java
package Test5;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Properties;

public class ScShell
{
	Properties proper=new Properties();
	private ScShell()
	{
		InputStream is=ScShell.class.getResourceAsStream("/scshell.properties");
		try
		{
			proper.load(is);
			is.close();
			
		} catch (IOException e)
		{
			System.out.println("properties load has problem!");
		}
	}
	
	public static void start() 
	{
		ScShell shell=new ScShell();
		
		System.out.println("------- ScShell Command Ui Framework ------");
		System.out.println("作者: 知飛翀");
		System.out.println("官網: http://biggerchong.cn");
		System.out.println("此演示程式是 Java學習指南(基礎篇) 的官網資料,最新版本請到官網下載!");
		System.out.println("\n");
		
		try
		{
			shell.process();
		} catch (IOException e)
		{
		
			System.out.println("process has problem!");
		}
	}
	
	private void process() throws IOException
	{
		InputStreamReader m=new InputStreamReader(System.in);
		BufferedReader reader=new BufferedReader(m);
		
		//讀取輸入內容
		while(true)
		{
			System.out.print("# ");
			
			String textline=reader.readLine();
			if(textline==null)
				break;
			
			if (textline == "exit")
			{
				System.out.println("good bye!");
				break;
			}
			//去除左右空格
			textline=textline.trim();
			handleCommand(textline);
		}
		reader.close();
	}
	
	private void handleCommand(String text) 
	{
		command cmd=new command();
		cmd.parser(text);
		String en=proper.getProperty(cmd.entrance).trim();
		
		if(en.length()==0)
			System.out.println("getPropwety has problem!");
		try
		{
		
			Class cls=Class.forName(en);
			Object obj=cls.newInstance();
			Method[] methods=cls.getMethods();
			Method method=null;
			for(pair a:cmd.p)
			{
				String key=a.k;
				String value=a.v;
				
				// 標準化setter的名字,例如 username -> setUsername
				char firstChar = Character.toUpperCase(key.charAt(0));
				StringBuffer strbuf = new StringBuffer("set" + key);
				strbuf.setCharAt(3, firstChar);
			
				
				for (Method m : methods)
				{
					if (m.getName().trim().equals(strbuf.toString()))
					{
						method = m;
						break;
					}
				}
				
				if(method==null)
					System.out.println("getMethod has problem!");
				
				Object[] parameter= {value};
				method.invoke(obj, parameter);
			}
			Method execute=cls.getMethod("execute", null);
			Integer returnValue=(Integer)execute.invoke(obj, null);
			System.out.println("------> return value = " + returnValue + " <--------");
		} catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
	//解析器
	private class pair
	{
		String k;
		String v;
		public pair()
		{
			
		}
		
		public pair(String k,String v)
		{
			this.k=k;
			this.v=v;
		}
	}
	
	private class command
	{
		String entrance=new String();
		ArrayList<pair> p=new ArrayList<pair>();
		
		public void parser(String textline)
		{
			String[] buf=textline.split(" ");
			this.entrance=buf[0].trim();
			
			p.clear();
			for(int i=1;i<buf.length;i++)
			{
				String[] aim=buf[i].trim().split("=");
				if(aim.length!=2)
					System.out.println("資料輸入錯誤!");
				String k=aim[0].trim();
				String v=aim[1].trim();
				p.add(new pair(k,v));
			}
		}
	}
	
	public static void main(String[] args)
	{
		// TODO Auto-generated method stub
		ScShell.start();
		
	}

	
}


//Scshell.properties

login=Test5.MyTest



//MyTest.java
package Test5;

public class MyTest
{
	String usename;
	String password;
	public void setUsename(String usename)
	{
		this.usename = usename;
	}
	public void setPassword(String password)
	{
		this.password = password;
	}
	public int execute()
	{
		if(this.usename.equals("shenchong")&&this.password.equals("123456"))
			System.out.println("登陸成功!");
		else
			System.out.println("登陸失敗!");
		return 0;
	}
	
	
}

執行結果如下:

謝謝觀看!如有不對請評論喲!