Java json && 框架中的 泛型 + 反射

前段时间再写SDK,需要接收服务器返回的json数据,于是定义了一个ResultDO

public class ApiResult<T> {
    private int code;
    private String msg;
    private T data;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code =code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

}

对于json的处理自然用到了gson库.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.1</version>
</dependency>

那数据如何转换呢?

public static <T>T fromJson(String json, Class<T> clz){
        return (T)gson.fromJson(json, clz);
    }

    public static String toJson(Object obj){
        return gson.toJson(obj);
    }

    public static <T> ApiResult<T> fromJson2(String json) {
        return (ApiResult<T>) gson.fromJson(
                 json, new TypeToken<ApiResult<T>>(){}.getType());
    }
//调用
//  
//  ApiResult<UserInfo> u = fromJson2(str);   

如果到这里就完了,那就没有后面的纠结了。
update:用法
reference
reference

//已经有一个对象,如何在对象内添加数据。
String tmp = gson.toJson(obj);
JsonParser jp = new JsonParser();
JsonObject jj2 = (JsonObject)jp.parse(tmp);
for (String key : map.keySet()) 
    jj2.add(key, gson.toJsonTree(map.get(key)));
System.out.println(jj2.toString());

//map 转换为 String
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("name", "xxx");
jsonObject.addProperty("value", "xxx");
Gson gson = new Gson();
String s = gson.toJson(jsonObject);

//string 转化为 map形式
String s = "{\"name\":\"xiaolin\",\"value\":\"xxx\"}";
JsonParser jp = new JsonParser();
JsonObject jo = (JsonObject)jp.parse(s);
System.out.println(jo.get("name").getAsString());


json.add(objName, gson.toJsonTree(obj));
//toJsonTree是转化为JsonElement,代表一个Json对象(子类有JsonArray JsonObject JsonNull等)。可以添加Type来使用泛型。

泛型

匿名内部类
获取泛型参数
Java泛型
Type
泛型中获得T.class
1. class

Object obj = new Object(); Object是obj的模板,obj.getClass()就是Object的模板,这个就是class类。那对于方法来说Type则是其模板。Class也继承自它。


type 是一种表示编程语言中的所有类型的类超级接口,如果 int Integer String 这都是表示一编程语言的类型,而其中的 int.class Integer.class String.class 它们表示的是类型的实例
如果,我们前面学习的反射 Class c = Integer.class Class 相当于表示类型的类,而Integer.class 则是一种
名为整形类型的类型实例 
理解了上面的那些,其 理解 type 就不难了,type 与 class 一样,不过 type 是一种比 Class 表示范围不要广的
超级接口,它表示Java语言中类型的所有接口

  1. Type
    我之前了解到的泛型是在编译器对代码进行检查,避免出错的。但是在框架中广泛用到泛型 + 反射。这样取得实际的类。这些内容在编译器也是确定的。运行时所有的泛型都是Object。
//方法1. 通过获得方法,再取得方法的类型参数,这样取得泛型的实际类型参数
import java.lang.reflect.*;
import java.util.*;

class Test {
    public static void main(String args[]) throws Exception {
        Method applyMethod=Test.class.getMethod("applyVector", Vector.class);
        Type[] types=applyMethod.getGenericParameterTypes();
        ParameterizedType pType=(ParameterizedType)types[0];
        System.out.println(pType.getActualTypeArguments()[0]);
        System.out.println(pType.getRawType());
    }
    public static void applyVector(Vector<Date> v1){ }
}
/**
输出:
class java.util.Date
class java.util.Vector
getActualTypeArguments 能取得实际类型参数,getRawType() 取得原本的类型。
*/

/**
getGenericSuperclass
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type.

对于带有泛型的class,返回一个ParameterizedType对象,对于Object、接口和原始类型返回null,对于数组class则是返回Object.class。ParameterizedType是表示带有泛型参数的类型的Java类型,JDK1.5引入了泛型之后,Java中所有的Class都实现了Type接口,ParameterizedType则是继承了Type接口,所有包含泛型的Class类都会实现这个接口

ParameterizedType是表示带有泛型参数的类型的Java类型 
如 Collection<String>


方法2. 这里的匿名内部类相当于写了个继承关系,取得了其父类内容。
*/
public static void main(String[] args) {  
        Test<String> test = new Test<String>(){}; 
        // 匿名内部类的声明在编译时进行,实例化在运行时进行  
        Type typeClass1 = test.getClass().getGenericSuperclass();  
        System.out.println(typeClass1);  

        if (typeClass1 instanceof ParameterizedType) {  
            Type actualType1 = ((ParameterizedType)typeClass1).getActualTypeArguments()[0];  

            System.out.println(actualType1);  
        } else {  
            System.out.println(typeClass1 + " is Not ParameterizedType");  
        }  
/**
Test<java.lang.String>  
class java.lang.String  
*/


// 经典例子
class TClass<T> {
}

class GoodClass<T> extends TClass<String> {
    public ParameterizedType getClassT() {
        return (ParameterizedType) getClass().getGenericSuperclass();
    }
}

class BadClass<T> extends TClass<T> {
    public ParameterizedType getClassT() {
        return (ParameterizedType) getClass().getGenericSuperclass();
    }
}

public class GenericsTest extends TestCase {

    private void print(Type[] targs) {
        System.out.print("actual type arguments are:");
        for (int j = 0; j < targs.length; j++) {
            System.out.print(" instance of " + targs[j].getClass().getName() + ":");
            System.out.println(" (" + targs[j] + ")");
        }
    }

    public void testGoodClass() throws Exception {
        ParameterizedType type = new GoodClass<Integer>().getClassT();
        Type[] types = type.getActualTypeArguments();
        print(types);

        assertEquals(TClass.class, type.getRawType());
        assertEquals(String.class, types[0]);
    }
    //error
    public void testBadClass() throws Exception {
        ParameterizedType type = new BadClass<String>().getClassT();
        Type[] types = type.getActualTypeArguments();
        print(types);

        assertEquals(TClass.class, type.getRawType());
        assertEquals(String.class, types[0]);
    }
}

框架中的使用。
在父类有一个子类的对象。

/**
clazz放在了超类,也就是声明泛型的那个类的构造方法中。这样一来,子类在继承具有泛型的超类时,会自动调用超类的构造方法。在此超类的构造方法中,调用的getClass返回的是子类的Class类型
*/
class BaseDaoImpl<T> {
    private Class<T> entityclass;
    public BaseDaoImpl() {
    try {
            Class<?> clazz = getClass(); //获取实际运行的类的 Class
            Type type = clazz.getGenericSuperclass(); //获取实际运行的类的直接超类的泛型类型
            if(type instanceof ParameterizedType){ //如果该泛型类型是参数化类型
                Type[] parameterizedType = ((ParameterizedType)type).getActualTypeArguments();//获取泛型类型的实际类型参数集
                entityClass = (Class<T>) parameterizedType[0]; //取出第一个(下标为0)参数的值
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("Type为: " + entityclass.getSimpleName());
    }
    public void save() {
        System.out.println("Type为: " + entityclass.getSimpleName());
    }
}

class UserDao extends BaseDaoImpl<Double>{}
class Test{
    public static void main(String[] args) {
        UserDao userdao=new UserDao();
        userdao.save();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值