首頁 >Java >java教程 >java之反射基礎

java之反射基礎

黄舟
黄舟原創
2017-02-24 09:51:161053瀏覽


1、反射是什麼


#  反射機制是在運行狀態中,對任意的一個類,都可以知道這個類的所有方法和屬性; 對於任何一個對象,都可以調用他的任意方法和屬性,這種1629896abeb295db4fa338b841891bcb的信息以及動態調用對象的方法稱為java的反射機制。

2、反射的作用

  • ##1、反編譯: .class–>java

  • 2 、透過反射機制存取物件的屬性,方法,建構方法等

3、反射的具體實作

3、1反射相關的類別

  • java.lang.Class;

  • java.lang.reflect.Constructor;

  • java.lang.reflect .Field;

  • java.lang.reflect.Method;

  • java.lang.reflect.Modifier;

#3.2 取得大Class物件的三種方式

由於任何類別都是Object的子類別而Object中有getClass可以取得

Class對象 -
public final native Class6b3d0130bba23ae47fe2b8e8cddf0195 getClass(); -

package com.chb.reflectTest;public class Test {
    public static void main(String[] args) throws Exception {        //第一种方式:
        Class<?> c1 = Class.forName("com.chb.reflectTest.Test");    //第二种方式:java中每个类都有class属性
        Class<?> c2 = Test.class;        //第三种方式:每个对象都与getClass()方法
        Class<?> c3 = new Test().getClass();
    }
}

3.3建立物件

  取得

Class物件以後,使用它建立對象,透過newInstance()呼叫無參構造函數進行建立對象,newInstance()返回一個Object物件:

Class<?> c1 = Class.forName("com.chb.reflectTest.Test");Object o1 = c1.newInstance();

3.4、取得資料

  分為所有屬性和製定的屬性

##3.4.1、取得所有屬性

    #取得修飾
    • 先透過屬性的getModifiers()取得修飾對象,
    • 再透過java.long. reflect.Modifier的toString()列印類別,屬性的修飾(public , static ,final等)。
    取得屬性
    • # 取得所有屬性:透過Class物件的getDeclaedFields(),傳回Filed的陣列* *。
    取得屬性的類型:
    • #透過屬性物件(Field物件)的getType()
    • Class<?> cString = Class.forName("java.lang.String");
              //获取累的修饰和名称
              System.out.print(Modifier.toString(cString.getModifiers())+" class " + cString.getSimpleName()+"{\n");
              //获取所有属性
              Field[] fields = cString.getDeclaredFields();
              for (Field field : fields) {
                  System.out.print("\t");
                  System.out.print(
                          Modifier.toString(field.getModifiers())+" "//属性的修饰
                        + field.getType().getSimpleName()+" "
                        + field.getName()+"\n");           
              }
              System.out.println("}");
    3.4.2 取得指定屬性

建立測試物件:

注意: 我在Use類別中定義了兩個屬性,一個public ,一個private ,是為了下一個測試反射可以打破封裝性

package com.chb.reflectTest;public class User {    
private String name;    
public  String nickName;    
public User() {}    
public User(String name, String nickName) {        
this.name = name;        
this.nickName = nickName;
    }
    setter getter...

}
傳統屬性的獲取和通過反射獲取對比:

package com.chb.reflectTest;import java.lang.reflect.Field;public class Test1 {
    public static void main(String[] args) throws Exception {
        //传统获取属性的值
        //1、通过getter,setter
        User user1 = new User();
        user1.setName("lisi");
        System.out.println(user1.getName());
        //2、直接调用属性
        User user2 = new User();
        user2.nickName = "癞皮狗";
        System.out.println(user2.nickName);
        //=========================================
        //通过反射来设置,获取属性。
        Class<User> c1 = (Class<User>) Class.forName("com.chb.reflectTest.User");
        User user = c1.newInstance();
        Field nickField = c1.getDeclaredField("nickName");
        nickField.set(user, "123");
        System.out.println(nickField.get(user));

        Field nameFiled = c1.getDeclaredField("name");
        //Exception in thread "main" java.lang.IllegalAccessException: 
        Class com.chb.reflectTest.Test1 can not access a member of class com.chb.reflectTest.User with modifiers "private"
        nameFiled.setAccessible(true);
        nameFiled.set(user, "oup");
        System.out.println(nameFiled.get(user));

    }
}

通過反射來設置屬性的值, 區別屬性的修飾範圍, 私有的不可以直接設定

會出現存取錯誤, 也就是java的安全存取機制,報錯:

Exception in thread "main" java.lang.IllegalAccessException: Class com.chb.reflectTest.Test1 can not access a member of class com.chb.reflectTest.
User with modifiers "private"

我們透過一個方法·來打破java的封裝性:

nameFiled.setAccessible(true);

1、反射是什麼

  反射機制是在

運行狀態中

,對任意的一個類,都可以知道這個類別的所有方法和屬性;對於任何一個對象,都可以呼叫他的任意方法和屬性,這種bb21fd6317999c350ac54256bc2251d5的資訊以及動態呼叫物件的方法稱為java的反射機制。 2、反射的作用

##1、反編譯: .class–>java
  • 2 、透過反射機制存取物件的屬性,方法,建構方法等
  • 3、反射的具體實作
3、1反射相關的類別

java.lang.Class;
  • java.lang.reflect.Constructor;
  • java.lang.reflect .Field;
  • java.lang.reflect.Method;
  • java.lang.reflect.Modifier;
  • #3.2 取得大Class物件的三種方式
由於任何類別都是Object的子類別而Object中有getClass可以取得

Class

對象 - public final native Class6b3d0130bba23ae47fe2b8e8cddf0195 getClass();
-<pre class="brush:java;toolbar:false;">package com.chb.reflectTest;public class Test { public static void main(String[] args) throws Exception { //第一种方式: Class&lt;?&gt; c1 = Class.forName(&quot;com.chb.reflectTest.Test&quot;); //第二种方式:java中每个类都有class属性 Class&lt;?&gt; c2 = Test.class; //第三种方式:每个对象都与getClass()方法 Class&lt;?&gt; c3 = new Test().getClass(); } }</pre>3.3建立物件

  取得

Class

物件以後,使用它建立對象,透過newInstance()呼叫無參構造函數進行建立對象,newInstance()返回一個Object物件:

Class<?> c1 = Class.forName("com.chb.reflectTest.Test");Object o1 = c1.newInstance();
3.4、取得資料

  分為所有屬性和製定的屬性

##3.4.1、取得所有屬性

#取得修飾

  • 先透過屬性的getModifiers()取得修飾對象,
    • 再透過java.long. reflect.Modifier的toString()列印類別,屬性的修飾(public , static ,final等)。

    • 取得屬性
  • # 取得所有屬性:透過Class物件的getDeclaedFields(),傳回Filed的陣列* *。
    • 取得屬性的類型:
      • 通过属性对象(Field对象)的getType()

    Class<?> cString = Class.forName("java.lang.String");
            //获取累的修饰和名称
            System.out.print(Modifier.toString(cString.getModifiers())+" class " + cString.getSimpleName()+"{\n");
            //获取所有属性
            Field[] fields = cString.getDeclaredFields();
            for (Field field : fields) {
                System.out.print("\t");
                System.out.print(
                        Modifier.toString(field.getModifiers())+" "//属性的修饰
                      + field.getType().getSimpleName()+" "
                      + field.getName()+"\n");           
            }
            System.out.println("}");

    3.4.2 获取指定属性

    创建测试对象:
    注意: 我在Use类中定义了两个属性, 一个public ,一个private ,是为了下一个测试反射可以打破封装性

    package com.chb.reflectTest;public class User {    
    private String name;    
    public  String nickName;    
    public User() {}    
    public User(String name, String nickName) {        
    this.name = name;        
    this.nickName = nickName;
        }
        setter getter...
    
    }

    传统属性的获取和通过反射获取对比:

    package com.chb.reflectTest;import java.lang.reflect.Field;public class Test1 {
        public static void main(String[] args) throws Exception {
            //传统获取属性的值
            //1、通过getter,setter
            User user1 = new User();
            user1.setName("lisi");
            System.out.println(user1.getName());
            //2、直接调用属性
            User user2 = new User();
            user2.nickName = "癞皮狗";
            System.out.println(user2.nickName);
            //=========================================
            //通过反射来设置,获取属性。
            Class<User> c1 = (Class<User>) Class.forName("com.chb.reflectTest.User");
            User user = c1.newInstance();
            Field nickField = c1.getDeclaredField("nickName");
            nickField.set(user, "123");
            System.out.println(nickField.get(user));
    
            Field nameFiled = c1.getDeclaredField("name");
            //Exception in thread "main" java.lang.IllegalAccessException: 
            Class com.chb.reflectTest.Test1 can not access a member of class com.chb.reflectTest.User with modifiers "private"
            nameFiled.setAccessible(true);
            nameFiled.set(user, "oup");
            System.out.println(nameFiled.get(user));
    
        }
    }

    通过反射来设置属性的值, 区别属性的修饰范围, 私有的不可以直接设置
    会出现访问错误, 也就是java的安全访问机制,报错:

    Exception in thread "main" java.lang.IllegalAccessException: Class com.chb.reflectTest.Test1 can not access a member of class com.chb.reflectTest.
    User with modifiers "private"

    我们通过一个方法·来打破java的封装性:

    nameFiled.setAccessible(true);

     以上就是java之反射基础的内容,更多相关内容请关注PHP中文网(www.php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn