反射及其应用

反射

     通过java反射机制,程序员可以更加深入的控制程序的运行过程,还可以逆向控制程序的执行过程;而这种功能是通过访问对象类构造函数、方法、成员实现的。

1、Class类

  Class类描述java程序中的各个java类;Class类的实例是字节码

  Class类对象的获取方式:  

    类名.class  ;   如:Student.class

    类对象.getClass();   如:stu.getClass();

    Class.forName();     如: Class.forName("java.lang.String ");

1、Constructor 类:访问构造函数

  方法:

  • getConstructors();

    获得所有权限为public的构造方法

  • gerConstructors(Class<>...... parameterTypes);

    获得权限为public的指定构造方法

  • getDeclaredConstructors();

    获得所有构造方法,按声明顺序返回;

  • getDeclaredConstructors(Class<>....... parameterTypes);

    获得指定构造方法

     例:

      ObjectClass。getDeclaredCOnstructor(String.class , int.class);

 

 Constructor类中一个非常重要的方法:

    newInstance(object   initargs);

      通过该构造方法创建一个指定类型的该类对象,如果没设置参数这表示采用默认无参数的构造方法;

 

2、Filed类:访问成员变量

   (给方法功能与Constructor相似)

  • getFileds();
  • getField(String name);
  • getDeclaredFileds();
  • getDeclaredFiled(String name);

 

Filed类中一个非常很重要的方法:

    setAccessible(boolean b);

      该方法可以设置是否忽略权限为private等私有权限的成员变量;为true是,允许使用该成员变量,即便其权限为private;

 

3、Method类:访问方法

  • getMethods();
  • getMethods(String name, Class<> ...... parameter);
  • getDeclaredMethods();
  • getDeclaredMethods(String name, Class<>......  parameter);

 

Method常用类中已给重要方法:

 

    invoke(Object obj, Object ......  args);

        l利用指定参数执行指定对象obj中的该方法,返回值为Object类型

    该方法在逆向控制中,非常实用。

 

4、反射应用  

   需求:利用反射实现扩展数组长度

 

 1 package unit16;
 2 
 3 import java.lang.reflect.*;
 4 
 5 public class ReFlexTest2 {
 6 
 7     public static void main(String[] args) {
 8 
 9         Test test = new Test();
10 
11         test.print();
12 
13         test.is = (int[]) addArrayLength(test.is, 10);
14         test.ss = (String[]) addArrayLength(test.ss, 10);
15 
16         test.print();
17 
18     }
19 
20     public static Object addArrayLength(Object array, int newLength) {
21         Object newArray = null;
22         Class componentType = array.getClass().getComponentType();//创建反射对象
23         newArray = Array.newInstance(componentType, newLength);//使用指定参数创建一个该类对象
24         System.arraycopy(array, 0, newArray, 0, Array.getLength(array));//通过替换,生成新数组
25         return newArray;
26     }
27 }
28 
29 class Test {
30 
31     public int[] is = { 1, 2, 3 };
32 
33     public String[] ss = { "A", "B", "C" };
34 
35     public void print() {//遍历数组
36 
37         for (int index = 0; index < is.length; index++) {
38             System.out.println("is[" + index + "]=" + is[index]);
39         }
40 
41         System.out.println();
42 
43         for (int index = 0; index < ss.length; index++) {
44             System.out.println("ss[" + index + "]=" + ss[index]);
45         }
46 
47         System.out.println();
48 
49     }
50 
51 }

 

 

 

 

例2: 使用反射初步验证用户输入信息

 

  1 /*
  2  * 通过反射初步验证用户输入信息
  3  */
  4 
  5 package unit16;
  6 
  7 import java.awt.*;
  8 import java.awt.event.*;
  9 import java.lang.reflect.*;
 10 
 11 import javax.swing.*;
 12 
 13 public class ReFlexTest extends JFrame{
 14 private JTextField textField_2;
 15     
 16     private JTextField textField_1;
 17     
 18     private JTextField textField;
 19     
 20     /**
 21      * Launch the application
 22      * 
 23      * @param args
 24      */
 25     public static void main(String args[]) {
 26         try {
 27             ReFlexTest frame = new ReFlexTest();
 28             frame.setVisible(true);
 29         } catch (Exception e) {
 30             e.printStackTrace();
 31         }
 32     }
 33     
 34     /**
 35      * Create the frame
 36      */
 37     public ReFlexTest() {
 38         super();
 39         setBounds(100, 100, 500, 375);
 40         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 41         
 42         final JPanel panel = new JPanel();
 43         panel.setLayout(new GridBagLayout());
 44         getContentPane().add(panel, BorderLayout.CENTER);
 45         //定义姓名文本框
 46         final JLabel label = new JLabel();
 47         label.setText("姓名:");
 48         final GridBagConstraints gridBagConstraints = new GridBagConstraints();
 49         gridBagConstraints.gridy = 0;
 50         gridBagConstraints.gridx = 0;
 51         panel.add(label, gridBagConstraints);
 52         textField = new JTextField();
 53         textField.setName("姓名");
 54         textField.setColumns(20);
 55         final GridBagConstraints gridBagConstraints_5 = new GridBagConstraints();
 56         gridBagConstraints_5.gridy = 0;
 57         gridBagConstraints_5.gridx = 1;
 58         panel.add(textField, gridBagConstraints_5);
 59         //定义性别单选按钮
 60         final JLabel label_1 = new JLabel();
 61         label_1.setText("性别:");
 62         final GridBagConstraints gridBagConstraints_1 = new GridBagConstraints();
 63         gridBagConstraints_1.gridy = 1;
 64         gridBagConstraints_1.gridx = 0;
 65         panel.add(label_1, gridBagConstraints_1);
 66         final JPanel panel_1 = new JPanel();
 67         final GridBagConstraints gridBagConstraints_4 = new GridBagConstraints();
 68         gridBagConstraints_4.gridy = 1;
 69         gridBagConstraints_4.gridx = 1;
 70         panel.add(panel_1, gridBagConstraints_4);
 71         
 72         final JRadioButton radioButton = new JRadioButton();
 73         radioButton.setText("男");
 74         panel_1.add(radioButton);
 75         
 76         final JRadioButton radioButton_1 = new JRadioButton();
 77         radioButton_1.setText("女");
 78         panel_1.add(radioButton_1);
 79         
 80         //定义出生日期文本框
 81         final JLabel label_2 = new JLabel();
 82         label_2.setText("出生日期:");
 83         final GridBagConstraints gridBagConstraints_2 = new GridBagConstraints();
 84         gridBagConstraints_2.gridy = 2;
 85         gridBagConstraints_2.gridx = 0;
 86         panel.add(label_2, gridBagConstraints_2);
 87         textField_1 = new JTextField();
 88         textField_1.setName("出生日期");
 89         textField_1.setColumns(20);
 90         final GridBagConstraints gridBagConstraints_6 = new GridBagConstraints();
 91         gridBagConstraints_6.gridy = 2;
 92         gridBagConstraints_6.gridx = 1;
 93         panel.add(textField_1, gridBagConstraints_6);
 94         
 95         //定义身份证文本框
 96         final JLabel label_3 = new JLabel();
 97         label_3.setText("身份证号:");
 98         final GridBagConstraints gridBagConstraints_3 = new GridBagConstraints();
 99         gridBagConstraints_3.gridy = 3;
100         gridBagConstraints_3.gridx = 0;
101         panel.add(label_3, gridBagConstraints_3);
102         textField_2 = new JTextField();
103         textField_2.setName("身份证号");
104         textField_2.setColumns(20);
105         final GridBagConstraints gridBagConstraints_7 = new GridBagConstraints();
106         gridBagConstraints_7.gridy = 3;
107         gridBagConstraints_7.gridx = 1;
108         panel.add(textField_2, gridBagConstraints_7);
109     
110     //定义确定按钮,并添加监听器
111         final JButton button = new JButton();
112         button.setText("确定");
113         button.addActionListener(new ActionListener() {
114             public void actionPerformed(ActionEvent e) {
115                 // 通过Java反射机制获得类中的所有属性
116                 Field[] fields = ReFlexTest.class.getDeclaredFields(); 
117                 for (int i = 0; i < fields.length; i++) { 
118                     Field field = fields[i]; 
119                     if (field.getType().equals(JTextField.class)) { // 只验证JTextField类型的属性
120                         field.setAccessible(true); // 默认情况下不允许访问私有属性,如果设为true则允许访问
121                         JTextField textField = null;
122                         try {
123                             textField = (JTextField) field.get(ReFlexTest.this); // 获得本类中的对应属性
124                         } catch (Exception ex) {
125                             ex.printStackTrace();
126                         }
127                         if (textField.getText().trim().length() == 0) { // 查看该属性是否为空
128                             String info = "请填写“" + textField.getName()
129                                     + "”!";
130                             JOptionPane.showMessageDialog(null, info,
131                                     "友情提示",
132                                     JOptionPane.INFORMATION_MESSAGE);
133                             textField.requestFocus(); // 令为空的文本框获得焦点
134                             return;
135                         }
136                     }
137                 }
138                 
139             }
140         });
141         final GridBagConstraints gridBagConstraints_8 = new GridBagConstraints();
142         gridBagConstraints_8.gridy = 4;
143         gridBagConstraints_8.gridx = 1;
144         panel.add(button, gridBagConstraints_8);
145         //
146     }
147 
148 }

 

 

总结: “反射就是把java类中的各种成分映射成相应的java类”,反射虽然可以逆向控制程序的执行,但这种方式会导致程序运行时间变长,效率降低。

    所以在使用反射方法时,要考虑到这对程序运行效率的影响。

 

 

 

 

 

 

 

posted @ 2015-06-30 16:08  池中月  阅读(801)  评论(0编辑  收藏  举报