聊聊泛型

我的主语言是java,之后用kotlin。
最近同事有个小问题,后端传回来的json数据需要解析,但它是这样的

{
    data{
        part{
            "key1":"5v"
            "key2":"3A"
        }
    },
    data{
        part{
            "key2":"1m"
            "key3":"4g"
            "key4":"7u"
            "key5":"9p"
        }
    }
}

于是他就有了想法做part的时候能不能不把所有的参数都放进去
我提了2个想法,一是建立database类,所有的part类都继承;2是使用泛型
可是后来我想行不通啊,gson传参的时候要求类型是给定的,两种想法都否定了
于是我就查到一篇帖子
说kotlin的泛型和java一样是假泛型,还用C#做对比。
其中确实了一点:Gson 没有办法根据 T 直接去反序列化。

泛型这个东西别称是‘参数化类型’,就是把一个确定的类型参数化了,变为不确定,在调用时传入具体类型。
操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
比如List就是经典使用,他的目的是在编译期检查出ClassCastException,防止运行时崩溃
而java在编译期后就开始去泛型化
说到泛型就不得不提通配符,当你的List中想包含父类和子类,纯泛型就做不到了,你就得用通配符

Generic<?> obj 可以放入任意类型的对象

然而这样还是有毛病,ClassCastException异常怎么办?
那就需要

Generic<? extends E>  obj//也称泛型上下边界

相对于泛型类来说,泛型方法稍微麻烦一点的

//在方法中使用了泛型,但并不是一个泛型方法,这只是类中一个普通的成员方法,只不过他的返回值是在声明泛型类已经声明过的泛型。
//所以在这个方法中才可以继续使用 T 这个泛型。
  public T getKey(){
      return key;
  }
/**泛型方法的基本介绍
 * @param tClass 传入的泛型实参
 * @return T 返回值为T类型
 * 说明:
 *     1)public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
 *     2)与泛型类的定义一样,<T>后面的T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
 *     3)Class<T>表明函数的传参tClass的类型为T,但相同的T表示的类可以不同
 *     4)静态方法
 */
public <T> T genericMethod(Class<T> tClass)throws InstantiationException ,
  IllegalAccessException{
        T instance = tClass.newInstance();
        return instance;
}
/** 
     * 这才是一个真正的泛型方法。
     * 首先在public与返回值之间的<T>必不可少,这表明这是一个泛型方法,并且声明了一个泛型T
     * 这个T可以出现在这个泛型方法的任意位置.
     * 泛型的数量也可以为任意多个 */
public <T,K> K showKeyName(Generic<T> container){
    }
/*此泛型方法使用泛型E,泛型E可以为任意类型,可以和类型T相同,也可以不同。
由于泛型方法在声明的时候会声明泛型<E>,
因此即使在泛型类中并未声明泛型,
编译器也能够正确识别泛型方法中识别的泛型。
*/
public <E> void show_3(E t){                     
    System.out.println(t.toString());
}     
/*使用泛型的静态方法
静态方法无法访问类上定义的泛型;
如果静态方法要使用泛型,必须将静态方法也定义成泛型方法 
*/
public static <T> void show(T t){

}

Object obj = genericMethod(Class.forName("com.test.test"));

我这里直接引用了博客里的段落
需要注意使用泛型的静态方法只能是泛型方法,public static void show(T t){..},这种编译器会提示错误信息:
“StaticGenerator cannot be refrenced from static context”
另外注释:
在java中是”不能创建一个确切的泛型类型的数组”的。
这句话是说你可以创建带通配符的泛型类型数组

//也就是说下面的这个例子是不可以的:
List<String>[] ls = new ArrayList<String>[10];  
//而使用通配符创建泛型数组是可以的,对于通配符的方式,最后取出数据是要做显式的类型转换的。
List<?>[] ls = new ArrayList<?>[10];  
//这样也是可以的:
List<String>[] ls = new ArrayList[10];

也就是说泛型类型数组,要么类型为通配符,要么实例化时省略类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值