java泛型理解。代码更明了。
泛型数据java基础,但真正理解需要悉心品尝。毕竟在工作中用到的是在是太多了。
不要以为new ArrayList<>这就是泛型,这只能属于会使用。
在工作中,相对于现有的项目源码的数据库操作层,无论是mybatis,hibernate或者是自己封装的baseModel层,都会使用到泛型。
以及<? extends T> 和 <? super T>这个屌东西。
泛型使用情况分为三类
1. 泛型类。
2. 泛型方法。
3. 泛型接口。
出于规范的目的,Java 还是建议我们用单个大写字母来代表类型参数。常见的如:
1. T 代表一般的任何类。
2. E 代表 Element 的意思,或者 Exception 异常的意思。
3. K 代表 Key 的意思。
4. V 代表 Value 的意思,通常与 K 一起配合使用。
5. S 代表 Subtype 的意思,文章后面部分会讲解示意。
最直接的一段代码。
List<String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass());
打印的判断为TRUE,因为泛型信息被擦除了。
泛型擦除实例。
List<String> listErasure = new ArrayList<String>() {
// 直接初始化,这也是一种方式。直接传入一个collection。
{add("aaa");add("bbb");}
};
listErasure.add("ccc");
Class<? extends List> class1 = listErasure.getClass();
Method method = class1.getMethod("add",Object.class);
method.invoke(listErasure, 123);
System.out.println(listErasure)
输出结果 [aaa, bbb, ccc, 123]
明明是接收String类型,但是却可以通过反射对其进行Integer类型的操作。
可见泛型只是在编译期间有效。
<?>
代表着类型未知
<? extends T> 和 <? super T>这个东西经常见到,但是并没有字面意义那么简单。
通配符有 3 种形式。
<?>
被称作无限定的通配符。<? extends T>
被称作有上限的通配符。<? super T>
被称作有下限的通配符。
class A{}
class B extends A{}
class C extends B{}
List<? extends B> listExtends = new ArrayList<B>();
// listExtends.add(new A()); 全部编译错误。因为使用的是extends,丧失了写的操作能力。跟f3方法一样,是未知类型,只是确定了里面对象的范围。是B的子类。
// listExtends.add(new B());
// listExtends.add(new C()); // 能进行对B以及B的子类操作。这是super的神奇之处。
List<? super B> listSuper = new ArrayList<B>();
// listSuper.add(new A());//会编译错误。
listSuper.add(new B());
listSuper.add(new C());
以及方法泛型的返回
泛型作为参数的传递。
public static <TTT>TTT f1(TTT t) {
return t;
} // 传递指定的A类型,对应的list可以进行对应的list应有的方法。
public static void f2(List<A> list) {
list.add(new A());
System.out.println(list.size());
} public static void f3(List<?> list) {
// list.add(new A()); //当传入的是?通配符的话表示只能进行跟?无关的操作,类似于size方法,增加代码的可读性。
System.out.println(list.size());
} public static void f4(List<? extends B> listExtends) {
// listExtends.add(new B());//不能进行写做操,因为是?,增加了可读性。
System.out.println(listExtends.size());
}
借鉴文章:泛型,一个孤独的守门者。
测试代码,很全面
package com.javaSE.fanxing; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List; class A{}
class B extends A{}
class C extends B{}
public class Demo<T,TT> {
T value;
TT value2;
public TT getValue2() {
return value2;
}
public void setValue2(TT value2) {
this.value2 = value2;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public static <TTT>TTT f1(TTT t) {
return t;
}
// 传递指定的A类型,对应的list可以进行对应的list应有的方法。
public static void f2(List<A> list) {
list.add(new A());
System.out.println(list.size());
}
public static void f3(List<?> list) {
// list.add(new A()); //当传入的是?通配符的话表示只能进行跟?无关的操作,类似于size方法,增加代码的可读性。
System.out.println(list.size());
}
public static void f4(List<? extends B> listExtends) {
// listExtends.add(new B());//不能进行写做操,因为是?,增加了可读性。
System.out.println(listExtends.size());
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
// 打印的判断为TRUE,因为泛型信息被擦除了。
List<String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass());
// 泛型擦除实例。
List<String> listErasure = new ArrayList<String>() {
// 直接初始化,这也是一种方式。直接传入一个collection。
{add("aaa");add("bbb");}
};
listErasure.add("ccc");
Class<? extends List> class1 = listErasure.getClass();
Method method = class1.getMethod("add",Object.class);
method.invoke(listErasure, 123);
System.out.println(listErasure); Demo<String,Integer> demo = new Demo<String,Integer>();
demo.setValue("string");
System.out.println(demo.getValue()); Demo<Integer,String> demo2 = new Demo<Integer,String>();
demo2.setValue(100);
System.out.println(demo2.getValue()); System.out.println(f1(123));
// List<A> listA = new ArrayList<A>();
// List<B> listB = listA;//new ArrayList<B>();虽然B是A的子类,并不代表泛型之间也具备继承关系。 ArrayList<A> listA = new ArrayList<A>();
listA.add(new A());
f3(listA); // 不对f3方法进行任何操作,是1.
f2(listA); // 2对应的方法实现还进行了一次插入操作。
f3(listA); // static ,对应的listA的集合数量是引用值。 ArrayList<B> listB = new ArrayList<B>();
listB.add(new B());
f3(listB); // f3方法传递的是通配符?,不能进行add操作。 // <? extends T> 和 <? super T>
List<? extends B> listExtends = new ArrayList<B>();
// listExtends.add(new A()); 全部编译错误。因为使用的是extends,丧失了写的操作能力。跟f3方法一样,是未知类型,只是确定了里面对象的范围。是B的子类。
// listExtends.add(new B());
// listExtends.add(new C()); // 能进行对B以及B的子类操作。这是super的神奇之处。
List<? super B> listSuper = new ArrayList<B>();
// listSuper.add(new A());//会编译错误。
listSuper.add(new B());
listSuper.add(new C()); // 没毛病。
List<B> listBS = new ArrayList<B>();
listBS.add(new B());
f4(listBS);
}
}
不要使用JDK中自带的sun.misc.BASE64Decoder这个类去BASE64,这个会在后面多加换行。使用apache中的org.apache.commons.codec.binary.Base64这个类就没问题
java泛型理解。代码更明了。的更多相关文章
- Java泛型理解
Java泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型.当需要使用某一种算法时,又无法具体算法的数据类型,或者想指定类型值的上限或下限,那么这时就需要Java泛型来大显身手 ...
- try-with-resources 让java资源关闭代码更简洁
一.JDK7的资源关闭方式优化 1 try-with-resource语法 在JDK7以前,Java没有自动关闭外部资源的语法特性,直到JDK7中新增了try-with-resource语法,才实现了 ...
- Java学习笔记(二一)——Java 泛型
[前面的话] 最近脸好干,掉皮,需要买点化妆品了. Java泛型好好学习一下. [定义] 一.泛型的定义主要有以下两种: 在程序编码中一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个 ...
- 重温Java泛型,带你更深入地理解它,更好的使用它!
1. 引言 jdk5.0中引入了Java泛型,目的是减少错误,并在类型上添加额外的抽象层. 本文将简要介绍Java中的泛型.泛型背后的目标以及如何使用泛型来提高代码的质量. 2. 为什么要用泛型? 设 ...
- 深入理解什么是Java泛型?泛型怎么使用?【纯转】
本篇文章给大家带来的内容是介绍深入理解什么是Java泛型?泛型怎么使用?有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所助. 一.什么是泛型 “泛型” 意味着编写的代码可以被不同类型的对象所 ...
- 大白话说Java泛型(二):深入理解通配符
文章首发于[博客园-陈树义],点击跳转到原文<大白话说Java泛型(二):深入理解通配符> 上篇文章<大白话说Java泛型(一):入门.原理.使用>,我们讲了泛型的产生缘由以及 ...
- Java泛型深入理解(转载)
原文地址 http://blog.csdn.net/sunxianghuang/article/details/51982979 泛型之前 在面向对象编程语言中,多态算是一种泛化机制.例如,你可以将 ...
- Java 泛型 <? super T> 中 super 怎么 理解?与 < ? extends T>有何不同?
Java 泛型 <? super T> 中 super 怎么 理解?与 extends 有何不同? 简介 前两篇文章介绍了泛型的基本用法.类型擦除以及泛型数组.在泛型的使用中,还有个重要的 ...
- Java 干货之深入理解Java泛型
一般的类和方法,只能使用具体的类型,要么是基本类型,要么是自定义的类.如果要编写可以应用多中类型的代码,这种刻板的限制对代码得束缚会就会很大. ---<Thinking in Java> ...
随机推荐
- IDEA调试服务器上部署的程序
提出问题: 一个程序,部署在自己的电脑上,debug调试,相信大家都会,但是,如果我想debug调试非本地部署的程序怎么办呢.比如测试服务器上部署的程序. 其实这样的需求也是经常有的,比如一个大型的项 ...
- POJ 2431 优先队列
汽车每过一单位消耗一单位油,其中有给定加油站可加油,问到达终点加油的最小次数. 做法很多的题,其中优先对列解这题是很经典的想法,枚举每个加油站,判断下当前油量是否小于0,小于0就在前面挑最大几个直至油 ...
- CSS 字体常用属性
一.字体大小 font-size:参数 /** * 参数:一.数字固定值,如20px * 二.父元素字体的百分比 * 三.smaller 比父元素更小 * 四.larger 比父元素更大 * 五.i ...
- 重构改善既有代码设计--重构手法16:Introduce Foreign Method (引入外加函数)&& 重构手法17:Introduce Local Extension (引入本地扩展)
重构手法16:Introduce Foreign Method (引入外加函数)你需要为提供服务的类增加一个函数,但你无法修改这个类.在客户类中建立一个函数,并以第一参数形式传入一个服务类实例. 动机 ...
- MongoDB - MongoDB CRUD Operations, Update Documents
Update Methods MongoDB provides the following methods for updating documents in a collection: Method ...
- C++ Boost库 uBLAS 笔记
构造 Vector #include <boost/numeric/ublas/vector.hpp> #include <boost/numeric/ublas/io.hpp> ...
- React Native 与 夜神模拟器的绑定
之前一直用真机去调试, 每回更新一次都需要手动摇晃手机后才能reload JS, OMG,太麻烦了. 后来寻思模拟器网上推荐用Geny...什么的模拟器,但是那个模拟器还需要VBox一起用. 有点麻烦 ...
- 47、求1+2+3+...+n
一.题目 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 二.解法 public class Solut ...
- Linux命令学习手册-route命令
route [-CFvnee] route [-v] [-A family] add [-net|-host] target [netmask Nm] [gw Gw] [metric N] [mss ...
- xargs -i 和-I 的区别【转】
xargs与find经常结合来进行文件操作,平时删日志的时候只是习惯的去删除,比如 # find . -type f -name "*.log" | xargs rm -rf * ...