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