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反射實現一個類的探查工具
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;
}
}