Java基础系列文章
Java基础(一):语言概述 | Java基础(二):原码、反码、补码及进制之间的运算 | Java基础(三):数据类型与进制 | Java基础(四):逻辑运算符和位运算符 |
|---|---|---|---|
Java基础(五):流程控制语句 | Java基础(六):数组 | Java基础(七):面向对象编程 | Java基础(八):封装、继承、多态性 |
Java基础(九):Object 类的使用 | Java基础(十):关键字static、代码块、关键字final | Java基础(十一):抽象类、接口、内部类 | Java基础(十二):枚举类 |
Java基础(十三):注解(Annotation) | Java基础(十四):包装类 | Java基础(十五):异常处理 | Java基础(十六):String的常用API |
Java基础(十七):日期时间API | Java基础(十八):java比较器、系统相关类、数学相关类 | Java基础(十九):集合框架 | Java基础(二十):泛型 |
Java基础(二十一):集合源码 | Java基础(二十二):File类与IO流 | Java基础(二十三):反射机制 | Java基础(二十四):网络编程 |
Java基础(二十五):Lambda表达式、方法引用、构造器引用 | Java基础(二十六):Java8 Stream流及Optional类 |
标识表示类中某个属性的类型或者是某个方法的返回值或参数的类型

举例:
//泛型在List中的使用
@Test
public void test1(){
//举例:将学生成绩保存在ArrayList中
//标准写法:
//ArrayList<Integer> list = new ArrayList<Integer>();
//jdk7的新特性:类型推断
ArrayList<Integer> list = new ArrayList<>();
list.add(56); //自动装箱
list.add(76);
list.add(88);
list.add(89);
//当添加非Integer类型数据时,编译不通过
//list.add("Tom");//编译报错
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()){
//不需要强转,直接可以获取添加时的元素的数据类型
Integer score = iterator.next();
System.out.println(score);
}
}类型参数,这里的"类型"习惯上使用T表示,是Type的缩写。即:<T>未知的数据类型,我们可以指定为<String>,<Integer>,<Circle>等泛型类或泛型接口【修饰符】 class 类名<类型变量列表> 【extends 父类】 【implements 接口们】{
}
【修饰符】 interface 接口名<类型变量列表> 【implements 接口们】{
}
//例如:
public class ArrayList<E>
public interface Map<K,V>{
....
} 之间声明类型变量,我们把声明了类型变量的方法,称为泛型方法[修饰符] <类型变量列表> 返回值类型 方法名([形参列表])[throws 异常列表]{
//...
}
//例如:java.util.Arrays类中的
public static <T> List<T> asList(T... a){
....
}必须使用引用数据类型。不能使用基本数据类型,此时只能使用包装类替换举例1:
class Person<T> {
// 使用T类型定义变量
private T info;
// 使用T类型定义一般方法
public T getInfo() {
return info;
}
public void setInfo(T info) {
this.info = info;
}
// 使用T类型定义构造器
public Person() {
}
public Person(T info) {
this.info = info;
}
// static的方法中不能声明泛型
//public static void show(T t) {
//
//}
// 不能在try-catch中使用泛型定义
//public void test() {
//try {
//
//} catch (MyException<T> ex) {
//
//}
//}
}举例2:
class Father<T1, T2> {
}
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son1 extends Father {// 等价于class Son extends Father<Object,Object>{
}
// 2)具体类型
class Son2 extends Father<Integer, String> {
}
// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2> extends Father<T1, T2> {
}
// 2)部分保留
class Son4<T2> extends Father<Integer, T2> {
}[访问权限] <泛型> 返回值类型 方法名([泛型标识 参数名称]) [抛出的异常]{
}static的举例1:
public final class GenericMethod {
public static <E> E get(int id, E e) {
E result = null;
return result;
}
public static <T> T post(String apiPath) {
return null;
}
public static void main(String[] args) {
// 可以根据类型推导出Boolean类型,所以.get之间的泛型<Boolean>可以省略
Boolean get = GenericMethod.get(2, Boolean.TRUE);
// 不能根据类型推导出Boolean类型,所以返回Object
Object post1 = GenericMethod.post("api");
// 此时<String>不可以省略
Integer post2 = GenericMethod.<Integer>post("api");
}
}举例2:
public static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
for (T o : a) {
c.add(o);
}
}
public static void main(String[] args) {
Object[] ao = new Object[100];
Collection<Object> co = new ArrayList<Object>();
fromArrayToCollection(ao, co);
String[] sa = new String[20];
Collection<String> cs = new ArrayList<>();
fromArrayToCollection(sa, cs);
}
public void testGenericAndSubClass() {
Person[] persons = null;
Man[] mans = null;
//Person[] 是 Man[] 的父类
persons = mans;
Person p = mans[0];
// 在泛型的集合上
List<Person> personList = null;
List<Man> manList = null;
//personList = manList;(报错)
}List<?>,Map<?,?> List<?>是List<String>、List<Object>等各种泛型List的父类写操作
Collection<?> c = new ArrayList<String>();
c.add(new Object()); // 编译时错误读操作
举例1:
public class TestWildcard {
public static void m4(Collection<?> coll){
for (Object o : coll) {
System.out.println(o);
}
}
}举例2:
public static void main(String[] args) {
List<?> list = null;
list = new ArrayList<String>();
list = new ArrayList<Double>();
// list.add(3);//编译不通过
list.add(null);
List<String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
l1.add("尚硅谷");
l2.add(15);
read(l1);
read(l2);
}
public static void read(List<?> list) {
for (Object o : list) {
System.out.println(o);
}
}public static <?> void test(ArrayList<?> list){
}class GenericTypeClass<?>{
}ArrayList<?> list2 = new ArrayList<?>();<?>:允许所有泛型的引用调用<? extends 类/接口 >:允许使用的类型必须是指定类/接口,或继承指定类、实现指定接口,即(子类)<=<? super 类/接口 >:允许使用的类型必须是指定类/接口,或指定类的父类、指定接口的父接口,即(父类)>=<? extends Number> //(无穷小 , Number]
//只允许泛型为Number及Number子类的引用调用
<? super Number> //[Number , 无穷大)
//只允许泛型为Number及Number父类的引用调用
<? extends Comparable>
//只允许泛型为实现Comparable接口的实现类的引用调用举例1
class Creature{}
class Person extends Creature{}
class Man extends Person{}
class PersonTest {
public static <T extends Person> void test(T t){
System.out.println(t);
}
public static void main(String[] args) {
test(new Person());
test(new Man());
test(new Creature());// 编译报错
}
}举例2:
public static void main(String[] args) {
Collection<Integer> list1 = new ArrayList<Integer>();
Collection<String> list2 = new ArrayList<String>();
Collection<Number> list3 = new ArrayList<Number>();
Collection<Object> list4 = new ArrayList<Object>();
getElement1(list1);
getElement1(list2);//报错
getElement1(list3);
getElement1(list4);//报错
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
}
// 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll){}
// 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll){}举例3:
@Test
public void test1(){
//List<Object> list1 = null;
List<Person> list2 = new ArrayList<Person>();
//List<Student> list3 = null;
List<? extends Person> list4 = null;
list2.add(new Person());
list4 = list2;
//读取:可以读
Person p1 = list4.get(0);
//写入:除了null之外,不能写入
list4.add(null);
// list4.add(new Person());
// list4.add(new Student());
}
@Test
public void test2(){
//List<Object> list1 = null;
List<Person> list2 = new ArrayList<Person>();
//List<Student> list3 = null;
List<? super Person> list5 = null;
list2.add(new Person());
list5 = list2;
//读取:可以实现
Object obj = list5.get(0);
//写入:可以写入Person及Person子类的对象
list5.add(new Person());
list5.add(new Student());
}