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