对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反射实现一个类的探查工具

对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;
	}
}



对Java反射机制的认识

上一篇:emacs lisp(elisp)程序像脚本一样运行


下一篇:mysql 1053错误,无法启动的解决方法