對Java反射機制的認識

1.        Java反射機制是動態語言的一種特質

動態類型語言和靜態類型語言的主要區別:在編譯期檢查變量類型還是在運行期檢查編譯類型,比如靜態語言:C,C++ 動態語言:Shell,python,JS 等。而反射允許Java把對某些類的類型檢查的過程推遲到運行時。

 

2.        反射的特點

反射機制允許程序在運行時透過Reflection APIs取得任何一個已知名稱的class的內部信息,允許運行中的 Java 程序對自身進行檢查,並能直接操作程序的內部屬性,甚至創建某個類的實例。這種編程方式可以讓對象在生成時才決定要生成哪一種對象。

 

3.        反射的優缺點

反射提高了編程時的靈活性,但是對性能有影響,就像HashMap和HashTable一樣。

 

4.        Java反射的核心類

java.lang.Class、java.lang.reflect.*
Field[] filedsList =( Class.forName(className)).getFields();
Method[] methodsList = =( Class.forName(className)).getMethods();
Constructor cons = testClass.getConstructor(argsClass);
Object o = cons.newInstance(args);

例子:

import java.lang.reflect.*;
public class TestReflect {
	
	public static void printFields(Field[] fields ){
		for( int i=0; i<fields.length; i++)
		System.out.println( fields[i].toString());
	}
	
	public static void printMethods(Method[] methods ){
		for( int i=0; i<methods.length; i++)
		System.out.println( methods[i].toString());
	}
	
	//運行時獲取某個類的屬性名和方法名
	public void getProptiesAndMethods(String className){
		try {
			Class testClass = Class.forName(className);
			Field[] filedsList = testClass.getFields();
//			System.out.println("各個字段:");
			printFields(filedsList);
			Method[] methodsList = testClass.getMethods();
//			System.out.println("\n各個方法:");
			printMethods(methodsList);	
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	//運行時新建某個類的實例
	public Object getNewInstance(String className, Object[] args){
		Object o = null;
		try {
			Class testClass = Class.forName(className);
			Class[] argsClass = new Class[args.length];                                  
			for (int i = 0, j = args.length; i < j; i++) {                               
			     argsClass[i] = args[i].getClass();                                       
			}   
			Constructor cons = testClass.getConstructor(argsClass); 
			o = cons.newInstance(args);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return o;
	}
	
	public int incrementField(String name, Object obj) {
		int value = 0;
		try{
	    Field field = obj.getClass().getDeclaredField(name);
	    value = field.getInt(obj) + 1;
	    field.setInt(obj, value);
		} catch (Exception e){
			e.printStackTrace();
		}
	    return value;
	}

	public static void main(String[] args){
		String classname = "java.lang.String";
		Test t = new Test("TT", 22);
		TestReflect tr = new TestReflect();
		tr.getProptiesAndMethods("java.util.Scanner");

//		Object[] cargs = {"TT"};
//		System.out.println(
//				((String)tr.getNewInstance("java.lang.String", cargs)).charAt(0) );
//		
//		t.introd();
//		tr.incrementField("age", t);
//		t.introd();
	}

5.        用Java反射實現一個類的探查工具



1百多行,就貼下源碼:
package hq.net.csdn.blog;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JTextArea;
/**
 * get class info by the class name.
 */
public class GetClassInfo extends JFrame{
	private static final long serialVersionUID = 1L;
	private static GetClassInfo mainWindow = null;
	private final int FRAME_WIDTH = 700;
	private final int FRAME_HEIGHT = 600;
	private final int PADDING_LEFT = 40;
	private final int BUTTON_HEIGTH = 30;
	private final int BUTTON_WIDTH = 50;
	private JLabel oLabel = null;
	private JTextField oTextField = null;
	private JButton oCheckButton = null;
	private JTextArea oTextArea = null;
	private JScrollPane oScrollPane = null;
	
	public GetClassInfo(){
		super();
		this.setSize(FRAME_WIDTH, FRAME_HEIGHT);
		this.getContentPane().setLayout(null);
		this.add(getJLabel(), null);
		this.add(getJTextField(), null);
		this.add(getCheckButton(), null);
		this.add(getTextArea(), null);
		this.add(getScrollPane(), null);
		this.setTitle("Reference Class");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	//label
	private JLabel getJLabel() {
		if ( null == oLabel ) {
			oLabel = new JLabel();
			oLabel.setBounds(PADDING_LEFT, 20, 150, BUTTON_HEIGTH);
			oLabel.setText("請輸入ClassName:");
		}
		return oLabel;
	}
	//text edit field for inputing class name 
	private JTextField getJTextField() {
		if ( null == oTextField ) {
			oTextField = new JTextField();
			oTextField.setBounds(PADDING_LEFT+130, 20, 330, BUTTON_HEIGTH);
		}
		return oTextField;
	}
	//check button
	private JButton getCheckButton(){
		if( null == oCheckButton ){
			oCheckButton = new JButton();
			oCheckButton.setBounds(PADDING_LEFT+500, 20, BUTTON_WIDTH*2, BUTTON_HEIGTH);
			oCheckButton.setText("Check");
			oCheckButton.addActionListener( new ActionListener(){
				
				@Override
				public void actionPerformed(ActionEvent evn) {
					String classname = oTextField.getText();
					oTextField.setText("");//clear edit text filed
					if( null==classname || "".equals( classname.trim())){
						JOptionPane.showMessageDialog(mainWindow, "Please Input Class Name!");
						return;
					}
					
					String classinfo = getClassInfo(classname);
					if( null==classinfo || "".equals( classinfo )) {
						JOptionPane.showMessageDialog(mainWindow, classname+ ": Class Not Found!");
						return;
					}
					oTextArea.setText( classinfo );
				}
			});
		}
		return oCheckButton;
	}
	//text area to display class info string
	public JTextArea getTextArea(){
		if( null == oTextArea ){
			oTextArea = new JTextArea();
		}
		return oTextArea;
	}
	//scroll panel
	public JScrollPane getScrollPane(){
		if( null == oScrollPane ){
			oScrollPane = new JScrollPane(oTextArea);
			oScrollPane.setBounds(PADDING_LEFT, 60, FRAME_WIDTH-100, FRAME_HEIGHT-150);
		}
		return oScrollPane;
	}
	//the main!
	public static void main(String args[]){
		mainWindow = new GetClassInfo();
		mainWindow.setVisible(true);
	}
	
	public String getClassInfo(String classname ){
		Class cl = null;
		Method[] methods = null;
		Field[] fields = null;
		String newline = "\r\n";
		String classinfo = null;
		//try to get class info by the classname
		try{
			classname = classname.trim();
			cl = Class.forName(classname);
			methods = cl.getDeclaredMethods();//get all methods and fields,
			fields = cl.getDeclaredFields();  //include private, protected and public 
		} catch (Exception e){
			e.printStackTrace();
			return classinfo;
		}
		classinfo = "---"+classname +"---"+ newline + "Fields:" + newline; 
		for( int i=0; i<fields.length; i++){
			classinfo += fields[i].toString() + newline;
		}
		classinfo += newline + "Methods:" + newline;
		for( int i=0; i<methods.length; i++){
			classinfo += methods[i].toString() + newline;
		}
		return classinfo;
	}
}



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