1. 程式人生 > >Java反射,泛型在Json中的運用

Java反射,泛型在Json中的運用

最近專案中遇到了Json資料自動獲取的功能,不然令人想起java的反射,已經很長時間沒複習java了正好一塊連java的這一塊內容一起過一遍。java中的反射無疑就相當於java開發者的春天,在眾多的框架中也能看到它的身影,可以在執行時檢查類,介面、變數和方法等資訊,可以例項化呼叫方法以及設定變數值等。本文主要以程式碼的形式直接將反射,泛型的運用展現出來。

java中的反射

首先新建一個基礎類Author。

package bean;
/**
 * 
 * @author Super~me
 * Description: 基礎類
 *
 */
public class Author {
    private static String TAG="Big";
    private String name;
    private int age;
    public Author(){}
    public Author(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
    public String toString() {
        return "Author [name=" + name + ", age=" + age + "]";
    }
    private String pMethod(String t){
        String result=t+" Private Method";
        return result;
    }
    

}

然後新建一個反射類,運用反射方法對上面的類進行訪問.包括對私有方法的訪問,對私有屬性的訪問等。其中常用的一些方法以及解釋:

//物件的建立
    public static void reflectNewInstance(){
        try {
            Class<?> authorclass=Class.forName(path_reflectfrom);
            Object object =authorclass.newInstance();
            Author author=(Author) object;
            author.setName("周大亨");
            author.setAge(89);
            System.out.println("author:  "+author.toString());
            
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    //對私有的方法進行反射
    public static void reflectPrivateConstructor(){
        try {
            Class<?> authorclass =Class.forName(path_reflectfrom);
            Constructor<?> declaredConstructor =authorclass.getDeclaredConstructor(String.class,int.class);
            declaredConstructor.setAccessible(true);
            Object object=declaredConstructor.newInstance("lida",88);
            Author author=(Author) object;
            System.out.println( "Author:  "+author.toString());
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    //反射私有的屬性
    public static void reflectPrivateField(){
        try {
            Class<?> authorclass =Class.forName(path_reflectfrom);
            Object authorobject=authorclass.newInstance();
            Field field=authorclass.getDeclaredField("TAG");
            field.setAccessible(true);
            String tag=(String)field.get(authorobject);
            System.out.println(  "private field Tag:"+tag);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    //反射獲取私有的方法
    private static void reflectMethod(){
        try {
            Class<?> authorclass=Class.forName(path_reflectfrom);
            Object authorobject=authorclass.newInstance();
            Method authormethod=authorclass.getDeclaredMethod("pMethod", String.class);
            authormethod.setAccessible(true);
            String string=(String)authormethod.invoke(authorobject, TAG);
            System.out.println( "private Method: "+string);
            
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
    }

通過控制檯列印以上資訊:檢視運用結果

ReflectClass.reflectNewInstance();
ReflectClass.reflectPrivateField();
ReflectClass.reflectPrivateConstructor();
ReflectClass.reflectMethod();

執行結果:

泛型的運用

對於泛型其實很好理解,通俗點講就是我們將型別也當成了引數進行傳值,這樣做程式碼的安全性很大的被提升了,也為較大的優化帶來可能。泛型可以使編譯器知道一個物件的限定型別是什麼,這樣編譯器就可以在一個高的程度上驗證這個型別消除了強制型別轉換 使得程式碼可讀性好,減少了很多出錯的機會。但是也要記住泛型的規範,比如靜態的變數和方法不能引用泛型變數,我們也不能利用instanceof等方法對泛型的型別進行判斷,當然這樣做也毫無意義,重要的一點是泛型類不能繼承Exception或者Throwable。泛型的繼承中,不論子類是否為泛型類,所繼承和實現的父類介面都有被指定。

常用的泛型型別變數:
E:元素(Element)
K:關鍵字(Key)
N:數字(Number)
T:型別(Type)
V:值(Value)
另外泛型界定的概念主要是指對泛型型別進行一個限定。比如:
public static <T extends String> T add(T str1, T str2) { return "";}

利用泛型和反射實現對json資料的儲存

//利用反射獲取json資料到java類
    private static void getJson(){
        try {
            String json = "{\"name\":\"Miss王\",\"age\":79}";         
            JSONObject source=JSONObject.parseObject(json); 
            Class<?> aClass = Class.forName("bean.Author");
            Object obj = aClass.newInstance();
            Field[] declaredFields = aClass.getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                System.out.println(source.getString(field.getName()));
                if (field.getGenericType().toString().equals(String.class.toString())) {
                    field.set(obj, source.getString(field.getName()));
                } else if (field.getGenericType().toString().equals(int.class.toString())) {
                    field.set(obj, source.getInteger(field.getName()));
                } 
            }
            Author author = (Author) obj;
            System.out.print(author);
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }

我們想把以上的實現封裝起來,這時就用了泛型。

 //泛型+反射實現json資料讀取到java類
    public static <T> T getJsonClass(String json, Class<T> beanclass) {
        try {
            JSONObject jsonObject = JSONObject.parseObject(json);
            Object obj = beanclass.newInstance();
            //拿到所以元素
            Field[] declaredFields = beanclass.getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                
                if (field.getGenericType().toString().equals(String.class.toString())) {
                    String value=jsonObject.getString(field.getName());
                    if(value!=null){
                     field.set(obj,value);
                    System.out.println(value);
                    }
                } else if (field.getGenericType().toString().equals(int.class.toString())) {
                    if(jsonObject.getInteger(field.getName())!=null)
                     field.set(obj,jsonObject.getInteger(field.getName()));
                     
                }
                
            }
            return (T) obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
  

呼叫實現:

public static void main(String[] args) {
        // TODO Auto-generated method stub
        String json = "{\"name\":\"李先生\",\"age\":82}"; 
        //ReflectJson.getJson();
        //解析json然後換成實體類
        Author author=getJsonClass(json, Author.class);
        System.out.print( author.toString());
    }

執行結果:

相關推薦

Java反射Json運用

最近專案中遇到了Json資料自動獲取的功能,不然令人想起java的反射,已經很長時間沒複習java了正好一塊連java的這一塊內容一起過一遍。java中的反射無疑就相當於java開發者的春天,在眾多的框架中也能看到它的身影,可以在執行時檢查類,介面、變數和方法等資訊,可以例項化呼叫方法以及設定變數值等。本文主

java集合簡單總結

容易 對象 並且 集合 需要 api文檔 array object 類型轉換 1.set中裝的對象是沒順序不可以重復。重復的判斷:只要兩個對象equals相等就行了。(要理解的是,並非重復了就報錯,只是存儲時候只有一個,輸出的時候只會輸出一個。) 2.list中的數據對象有

Java反射和註解實戰之Spring核心注入IOC的實現

一.前言 通過前兩篇文章的學習,我們已經對Java中這三個模組的知識有了初步的瞭解。為了將鞏固之前的知識,今天我們將綜合運用這三個模組的知識,來實現一個類似Spring中注入的案例。 二.專案結構 簡單的描繪了一下專案流程圖,

java反射

黑馬程式設計師_反射和泛型---------------------- <a href="http://edu.csdn.net/heima" target="blank">android培訓</a>、<a href="http://edu.c

java反射+列舉+

反射: 1.呼叫反射的三種方法 2.class.forName 動態編譯 靜態載入類,是編譯時刻載入;動態載入類,是執行時刻載入new建立物件:是靜態載入類,在編譯時刻就需要載入所有的【可能使用到的類】。有一個類有問題(如不存在),都不能通過編譯,會報錯。Class.fo

java反射獲取

public class Person<T> { } import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class Student ext

深入分析Java反射(三)-

前提 Java反射的API在JavaSE1.7的時候已經基本完善,但是本文編寫的時候使用的是Oracle JDK11,因為JDK11對於sun包下的原始碼也上傳了,可以直接通過IDE檢視對應的原始碼和進行Debug。 本文主要介紹反射中一個比較難的問題-泛型。 泛型的簡介 泛型是在2004年JavaSE 5.

C#反射 字符串轉為實體類並做為參數傳入方法使用

subst type xxd main.c 發現 get director col asm 工作中有這樣一個需求,有N張不同的報表,每張報表對應一個數據源,以前采用SQL統計方式 ,統計數據采用內存方式,首先在內在裏定義了數據源對應實體。統計條件用lamdba表達式式實現,

Java基礎系列(三十七):繼承萬用字元反射

泛型型別的繼承規則 首先,我們來看一個類和它的子類,比如 Fruit 和 Apple。但是Pair<Apple>是Pair<Fruit>的一個子類麼?並不是。比如下面的這段程式碼就會編譯失敗: Apple[] apples = ...; Pair<F

Java通過反射獲取例項

首先,建立一個Students的實體類 package com.jackie.day11; import java.io.Serializable; import java.util.Date;

java機制學習——反射註解代理

java 反射機制在很多地方都有用到。 1、反射的概念: JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意方法和屬性;這種動態獲取資訊以及動態呼叫物件方法的功能稱為java語言的反射機制。 Ja

抽象json轉換型別丟失解決辦法

在 抽象泛型類中,一般會自動將資料轉換操作實現,使用者就不用關心資料轉換過程,專注業務處理就行了 重新實現TypeRe

Java之集合初探(二)Iterator(叠代器)collections打包/解包(裝箱拆箱)(Generic)comparable接口

基本 generate 等於 框架 ring bin list() each 是否 Iterator(叠代器) 所有實現了Collection接口的容器都有一個iterator方法, 用來返回一個實現了Iterator接口的對象 Iterator對象稱作叠代器, 用來

java異常、反射

(1)異常 異常的概念:所謂異常是指程式在執行過程中發生的一些不正常事件。(如:除0溢位,陣列下標越界,所讀取的檔案不存在) 異常導致的結果:java程式的執行過程中如出現異常事件,可以生成一個異常類物件。該異常物件封裝了異常事件的資訊,並將其提交給java執行時系統,這個過程成為丟擲異

Java集合總結機制可變引數

List實現類的區別及適用場景   底層實現 優缺點 執行緒是否安全 效率 適用場景 ArrayList 陣列 查詢易,增刪難 否 高

java 通過反射獲取的型別

分享一下我老師大神的人工智慧教程吧。零基礎,通俗易懂!風趣幽默!http://www.captainbed.net/ 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

java-陣列以及列舉

列舉: java不允許用=為列舉常量賦值,列舉中的構造方法必須為private修飾 列舉中values方法將列舉型別的成員以陣列的形式返回 toString方法能夠返回列舉常量名 ordinal方法返回enumeration宣告中列舉常量的位置 列舉是一個類,可以有自己的屬性和方法並且實現

實現ApplicationContextAware介面java(new或者java反射獲取的物件)獲取spring容器的bean

本文參考了https://blog.csdn.net/bailinbbc/article/details/76446594,其實是拷貝了很多內容: 在Web應用中,Spring容器通常採用宣告式方式配置產生:開發者只要在web.xml中配置一個Listener,該Listener將會負責初始化S

Java反射 & 反射效能 & 反射操作 & 反射操作註解

反射機制 執行時載入,探知,使用編譯期間完全未知的類。 程式在執行狀態中,可以動態載入一個只有名稱的類,對於任意一個已載入的類,都能夠知道這個類的所有屬性和方法,對於任意一個物件,都能夠呼叫他的任意一個方法和屬性。 jvm載入完類之後,在堆記憶體中,就產生了一個對應的C

java反射(10) 使用反射獲取資訊

前面說活可以通過Class物件可以獲得成員變數的型別,不管該成員變數是不是私有的,但是如果成員變數是有泛型型別的引數的話,如Map<String, Integert>那麼將無法獲得其泛型引數的資訊。 想要獲得泛型引數的資訊應該使用以下步驟: 將Type物件強制