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
//建立
- Class cls=String.class;
- String str="中國你好"; Class cls=str.getClass();
- 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;
}
}
執行結果如下:
謝謝觀看!如有不對請評論喲!