zoukankan      html  css  js  c++  java
  • Java 反射

    在编译过程中,无法预知该对象,类或者可能属于那些类,只能依靠程序运行时信息来发现该对象和类的真实信息,而从程序运行过程中,实现程序运行时获取对象和类的信息,这就是反射

    获取类

    通过反射获取类的方法有如下:

    public class Test {
        public int a;
        public int b;
        private int c;
        private int d;
        public String aa;
        private String bb;
        
        public Test(){}
        public Test(int a,int b,int c,int d){
            this.a=a;
            this.b=b;
            this.c=c;
            this.d=d;
        }
        private Test(int c,int d){
            this.c=c;
            this.d=d;
        }
        
        public int getA() {
            return a;
        }
        public void setA(int a) {
            this.a = a;
        }
        public int getB() {
            return b;
        }
        public void setB(int b) {
            this.b = b;
        }
        public int getC() {
            return c;
        }
        public void setC(int c) {
            this.c = c;
        }
        public int getD() {
            return d;
        }
        public void setD(int d) {
            this.d = d;
        }
        private void A(){
            System.out.println("哈哈哈");
        }
        public void B(){
            System.out.println("fdsa");
        }
        @Override
        public String toString() {
            return "Test [a=" + a + ", b=" + b + ", c=" + c + ", d=" + d + ", aa=" + aa + ", bb=" + bb + "]";
        }
    }
    View Code
    Class<?> class_1 = Class.forName("Test");  //方法一,使用Class类的forName(String clazzName)静态方法
    Class<?> class_2 = Test.class;             //方法二,调用类的class属性获取该类的对应Class对象
    Test test = new Test();                    
    Class<?> testClass = test.getClass();      //方法三,调用某个对象的getClass()方法。

    其中,方法一和方法二都是直接根据类来取得该类的class对象,方法三则是通过类的对象取得该类的class对象。

    方法一和方法二相比之下,方法二较有优势:1,代码更安全,编译时可以;2,程序性能更好,因为无需调用方法;

    获取类信息

     1. 获取类的构造方法(构造器)

    //获取用public修饰指定参数的构造方法,如要获取默认构造方法,参数为Test.class
    Constructor<?> constructor_1 = Test.class.getConstructor(Test.class);   //getConstructor(Class<?>...parameterTypes)
    //获取所有用public修饰的构造方法
    Constructor<?>[] constructor_2 = Test.class.getConstructors();          //getConstructors()    
    //获取指定参数的构造方法
    Constructor<?> constructor_3 = Test.class.getDeclaredConstructor();     //getDeclaredConstructor(Class<?>...parameterTypes);
    //获取所有的构造方法
    Constructor<?>[] constructor_4 = Test.class.getDeclaredConstructors();  //getDeclaredConstructors

     2. 获取类的属性

    //获取public修饰并指定的属性名
    Field feild_1 = Test.class.getField("a");          //getField(String name);
    //获取public修饰的所有属性名
    Field[] feild_2 = Test.class.getFields();          //getFields();
    //获取指定的属性名
    Field feild_3 = Test.class.getDeclaredField("c");  //getDeclaredField(String name);
    //获取所有的属性名
    Field[] feild_4 = Test.class.getDeclaredFields();  //getDeclaredFields();

     3. 获取类的方法

    //获取public修饰并指定的方法
    Method method_1 = Test.class.getMethod("getA");  //getMethod(String name,Class<?>...parameterTypes);
    //获取public修饰的所有方法
    Method[] method_2 = Test.class.getMethods(); //getMethods() //获取指定的方法 Method method_3 = Test.class.getDeclaredMethod("A"); //getDeclaredMethod(String name,Class<?>...parameterTypes); //获取所有的方法
    Method[] method_4 = Test.class.getDeclaredMethods(); //getDeclaredMethods()

    使用反射生成并操作对象

    1. 创建对象

    //创建默认构造方法的对象(无默认构造方法则报错)
    Object test_1 = Test.class.newInstance();
    //创建指定构造方法的对象(可以是默认构造方法)
    Constructor<?> constructor = Test.class.getDeclaredConstructor(int.class,int.class,int.class,int.class); Object test_2 = constructor.newInstance(1,3,4,5);

    2. 调用方法

    Object obj = method_1.invoke(test_1);   //method.invoke(Object obj,Object...parameterTypes) 第一个参数为对应类的对象,第二个参数为该方法的参数

    3. 访问属性值

    Test test = new Test();                                //获取对象
    Field fieldI = Test.class.getDeclaredField("c");       //获取私有属性c
    Field fieldII = Test.class.getField("aa");             //获取属性aa
    Field fieldIII = Test.class.getDeclaredField("bb");    //获取私有属性bb
    fieldI.setAccessible(true);                            //解除访问限制

     fieldI.setInt(test,1);              //八大基本数据类型设置属性 方法一 setXxx(Object obj,Xxx val) Xxx指八大基本数据类型,其中首字母大写
     Object obj_1 = fieldI.getInt(test); //八大基本数据类型获取属性 方法一 getXxx(Object obj,Xxx val) Xxx指八大基本数据类型,其中首字母大写
     System.out.println(obj_1);
     fieldI.set(test,12);                //八大基本数据类型设置属性 方法二 set(Object obj,Obj val)
     Object obj_2 = fieldI.get(test);    //八大基本数据类型获取属性 方法二 get(Object obj)
     System.out.println(obj_2);
     fieldII.set(test,"Test");           //复合数据类型设置属性 set(Object obj,Obj val)
     Object obj_3 = fieldII.get(test);   //复合数据类型获取属性 get(Object obj)
     System.out.println(obj_3);
     System.out.println(test);
     fieldIII.set(test,"哈哈");
     System.out.println(test);

     

     全部代码:

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class TestMain {
        public static void main(String[] args){
            
            try {
                Class<?> class_1 = Class.forName("Test");  //方法一
                Class<?> class_2 = Test.class;             //方法二
    //            Test test = new Test();                    
    //            Class<?> class_3 = test.getClass();      //方法三
                
                System.out.println("--------类----------");
                System.out.println("1"+class_1);
                System.out.println("2"+class_2);
    //            System.out.println("3"+class_3);
                
                Constructor<?> constructor_1 = Test.class.getConstructor();
                Constructor<?>[] constructor_2 = Test.class.getConstructors();
                Constructor<?> constructor_3 = Test.class.getDeclaredConstructor();
                Constructor<?>[] constructor_4 = Test.class.getDeclaredConstructors();
                
                System.out.println("--------构造方法----------");
                System.out.println(constructor_1);
                System.out.println(constructor_2);
                System.out.println(constructor_3);
                System.out.println(constructor_4);
                
                //获取public修饰并指定的属性名
                Field feild_1 = Test.class.getField("a");          //getField(String name);
                //获取public修饰的所有属性名
                Field[] feild_2 = Test.class.getFields();          //getFields();
                //获取指定的属性名
                Field feild_3 = Test.class.getDeclaredField("c");  //getDeclaredField(String name);
                //获取所有的属性名
                Field[] feild_4 = Test.class.getDeclaredFields();  //getDeclaredFields();
                
                System.out.println("--------类的属性----------");
                System.out.println(feild_1);
                System.out.println(feild_2);
                System.out.println(feild_3);
                System.out.println(feild_4);
                
                //获取public修饰并指定的方法
                Method method_1 = Test.class.getMethod("getA");  //getMethod(String name,Class<?>...parameterTypes);
                //获取public修饰的所有方法
                Method[] method_2 = Test.class.getMethods();     //getMethods()
                //获取指定的方法
                Method method_3 = Test.class.getDeclaredMethod("A");  //getDeclaredMethod(String name,Class<?>...parameterTypes);
                //获取所有的方法
                Method[] method_4 = Test.class.getDeclaredMethods();  //getDeclaredMethods()
                
                System.out.println("--------类的方法----------");
                System.out.println(method_1);
                System.out.println(method_2);
                System.out.println(method_3);
                System.out.println(method_4);
                
                //创建默认构造方法的对象(无默认构造方法则报错)
                Object test_1 = Test.class.newInstance();
                //创建指定构造方法的对象(可以是默认构造方法)
                Constructor<?> constructor = Test.class.getDeclaredConstructor(int.class,int.class,int.class,int.class);
                Object test_2 = constructor.newInstance(1,3,4,5);
                System.out.println("--------创建对象----------");
                System.out.println(test_1);
                System.out.println(test_2);
                
                Object obj = method_1.invoke(test_1);
                System.out.println("--------方法调用----------");
                System.out.println(obj);
                
                Test test = new Test();
                Field fieldI = Test.class.getDeclaredField("c");
                Field fieldII = Test.class.getField("aa");
                Field fieldIII = Test.class.getDeclaredField("bb");
                fieldI.setAccessible(true);
                
                System.out.println("--------属性访问----------");
                fieldI.setInt(test,1);               //八大基本数据类型设置属性 方法一 setXxx(Object obj,Xxx val) Xxx指八大基本数据类型,其中首字母大写      
                Object obj_1 = fieldI.getInt(test);  //八大基本数据类型获取属性 方法一 getXxx(Object obj,Xxx val) Xxx指八大基本数据类型,其中首字母大写
                System.out.println(obj_1);
                fieldI.set(test,12);                 //八大基本数据类型设置属性 方法二 set(Object obj,Obj val)
                Object obj_2 = fieldI.get(test);     //八大基本数据类型获取属性 方法二 get(Object obj)
                System.out.println(obj_2);
                fieldII.set(test,"Test");            //复合数据类型设置属性 set(Object obj,Obj val)
                Object obj_3 = fieldII.get(test);    //复合数据类型获取属性 get(Object obj)
                System.out.println(obj_3);
                System.out.println(test);            
                fieldIII.set(test,"哈哈");
                System.out.println(test);
                
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    }
    View Code
  • 相关阅读:
    Largest Submatrix of All 1’s
    Max Sum of Max-K-sub-sequence
    Sticks Problem
    Splay模版
    B. Different Rules
    链表合并 leetcode
    K个一组翻转链表
    反转链表2 leetcode
    nodejs简单仿apache页面
    HTML 5 Web Workers
  • 原文地址:https://www.cnblogs.com/hjlin/p/11365292.html
Copyright © 2011-2022 走看看