1、什么是泛型?
泛型(Generics)是把类型参数化,运用于类、接口、方法中,在调用时传入具体的类型。

泛型就是参数化类型

  1. 适用于多种数据类型执行相同的代码
  2. 泛型的类型在使用时指定
  3. 泛型归根到底就是“模板”

优点:使用泛型时,在实际使用之前类型就已经确定了,不需要强制类型转换。

操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

2、泛型的使用场景

2.1 用于集合

/*** 运用于集合中*/
public class Demo01 {//不使用泛型,直接存取数据public static void test01() {List list = new ArrayList();list.add("001");list.add(100);Object o1 = list.get(1);if(o1 instanceof Integer) {//如果不判断类型,直接强转Integer,则运行时可能直接抛出异常o1 = (Integer)o1;}System.out.println(o1);}public static void test02() {List<Integer> list = new ArrayList<Integer>();//list.add("001"); 放数据时进行安全检查,"001"不是Integer类型,编译不通过list.add(100);System.out.println(list.get(0));}public static void main(String[] args) {test01();test02();}
}

2.2 自定义泛型

泛型字母

  1. 形式类型参数(formal type parameters)即泛型字母
  2. 命名泛型字母可以随意指定,尽量使用大写字母(多个参数时,在字母后加数字,例T1,T2)
  3. 常见字母:T(Type),K V (Key Value),E(Element)

 泛型类

  • 只能用在成员变量上,只能使用引用类型

泛型接口

  • 只能用在抽象方法上

泛型方法

  • 返回值前加<T>

自定义泛型类

/*** 自定义泛型类* @param <T>*/
class Student<T> {private T prop;public T getProp() {return prop;}public void setProp(T prop) {this.prop = prop;}@Overridepublic String toString() {return "Student [prop=" + prop + "]";}
}public class Demo02 {public static void main(String[] args) {//Student<int> s = new Student<int>(); 不能为基本类型,会编译报错Student<Integer> student = new Student<Integer>();student.setProp(18);//输出:Student [prop=18]System.out.println(student);}
}

自定义泛型接口

/*** 自定义泛型接口* 接口中泛型字母只能使用在方法中,不能使用在全局常量中* @param <T>*/
public interface Comparator<T1, T2> {//public static T1 param; 静态类型不能引用非静态的参数,会编译报错void compare(T1 t1);T2 compare();public abstract T1 compare2(T2 t2);
}

非泛型类里定义泛型方法

/*** 非泛型类里定义泛型方法*/
public class Demo03 {public static<T> void test01(T t) {System.out.println(t);}public static<T extends List> void test02(T t) {t.add("sdfs");System.out.println(t);}public static <T extends Object> void test03(T ...l) {for(T t:l) {System.out.println(t);}}public static void main(String[] args) {//泛型参数test01("01");//泛型的继承test02(new ArrayList<Integer>());//可变参数test03(new ArrayList<Integer>(), new ArrayList<String>());}}

泛型类的继承

abstract class Father<T1, T2> {T1 age;public abstract void makeFriend(T2 t);
}/*** 父类泛型完全保留*/
class Child1<T1, T2> extends Father<T1, T2> {@Overridepublic void makeFriend(T2 t) {System.out.println("My attr: "+age+" &T2="+t);System.out.println("I am "+getClass().getName()+", let`s be friend.");}
}/*** 父类泛型部分保留*/
class Child2<T1> extends Father<T1, Integer> {@Overridepublic void makeFriend(Integer t) {System.out.println("My attr: "+age+" &T2="+t);System.out.println("I am "+getClass().getName()+", let`s be friend.");}
}/*** 父类泛型不保留,子类按需实现*/
class Child3 extends Father<Integer, String> {@Overridepublic void makeFriend(String t) {System.out.println("My attr: "+age+" &T2="+t);System.out.println("I am "+getClass().getName()+", let`s be friend.");}
}/*** 没有具体类型* 泛型擦除,继承父类的子类,没有指定类型,默认为Object*/
@SuppressWarnings("rawtypes")
class Child4 extends Father {@Overridepublic void makeFriend(Object t) {System.out.println("My attr: "+age+" &T2="+t);System.out.println("I am "+getClass().getName()+", let`s be friend.");}
}public class Demo03 {public static void main(String[] args) {new Child1().makeFriend("1");new Child2().makeFriend(1);new Child3().makeFriend("1");new Child4().makeFriend("1");}
}
/*** 类型擦除*/
public class Demo03 {public static void test01(Student<Integer> student) {student.setProp(18);System.out.println(student);}public static void main(String[] args) {Student student = new Student();//输出:Student [prop=18]test01(student);Student<String> s2 = new Student<String>();//编译报错,参数不匹配//test01(s2);}
}

通配符

通配符(Wildcards)

  1. T、K、V、E 等泛型字母为有类型,类型参数赋予具体的值
  2. ?未知类型 类型参数赋予不确定值,任意类型
  3. 只能用在声明类型、方法参数上,不能用在定义泛型类上

/*** 泛型的通配符,类型不确定,用于变量声明或者形参上面* 不能用在类上或者对象创建上*/
public class Demo03 {public static<T> void test01(Student<T> student) {//编译报错:不能转换 Student<Integer> 为 Student<T>//student = new Student<Integer>();//student = new Student<String>();//student = new Student<BigDecimal>();System.out.println(student);}public static void test02(Student<?> student) {//?号代表类型参数不确定,下面代码可以执行student = new Student<Integer>();student = new Student<String>();student = new Student<BigDecimal>();System.out.println(student);}public static void main(String[] args) {Student student = new Student();//输出:Student [prop=null]test02(student);}
}

extends/super

上限(extends)
指定的类必须是继承某个类,或者实现了某个接口(不是implements),即<=

  • ? extends List

下限(super)

即父类或本身

  • ? super List

/*** extends:泛型的上限 <= 一般用于限制操作 不能使用在添加数据上,一般都是用于数据的读取* supper:泛型的上限 >= 即父类或自身。一般用于下限操作*/
public class Demo03<T extends Fruit> {public static void test01() {Demo03<Fruit> t1 = new Demo03<Fruit>();Demo03<Apple> t2 = new Demo03<Apple>();//编译报错:类型转换失败//Demo03<Fruit> t3 = new Demo03<Apple>();}public static void test02(List<? extends Fruit> list) {//编译报错//list.add(new Fruit());//list.add(new Object());}public static void test03(List<? super Apple> list) {//可以编译通过list.add(new Apple());list.add(new RedApple());//编译报错//list.add(new Fruit());}}

泛型嵌套

/*** 泛型嵌套**/
public class Demo05 {public static void main(String[] args) {Student2<String> student = new Student2<String>();student.setScore("优秀");System.out.println(student.getScore());//泛型嵌套School<Student2<String>> school = new School<Student2<String>>();school.setStu(student);String s = school.getStu().getScore(); //从外向里取System.out.println(s);// hashmap 使用了泛型的嵌套Map<String, String> map =  new HashMap<String,String>();map.put("a", "张三");map.put("b", "李四");Set<Entry<String, String>> set = map.entrySet();for (Entry<String, String> entry : set) {System.out.println(entry.getKey()+":"+entry.getValue());}}
}public class School<T> {private T stu;public T getStu() {return stu;}public void setStu(T stu) {this.stu = stu;}}public class Student2<T> {T score;public T getScore() {return score;}public void setScore(T score) {this.score = score;}
}

其他(数组)

 import java.util.ArrayList;
import java.util.List;/*** 泛型没有多态* 泛型没有数组* JDK1.7对泛型的简化* @author Administrator**/
public class Demo06 {public static void main(String[] args) {Fruit fruit = new Apple();  // 多态,父类的引用指向子类的对象//List<Fruit> list = new ArrayList<Apple>(); //泛型没有多态 List<? extends Fruit> list = new ArrayList<Apple>();//泛型没有数组//Fruit<String>[] fruits = new Fruit<String>[10];//ArrayList底层是一个Object[],它放数据的时候直接放,取数据的时候强制类型转化为泛型类型/*public boolean add(E e) {ensureCapacityInternal(size + 1);  // Increments modCount!!elementData[size++] = e;return true;}*//*E elementData(int index) {return (E) elementData[index];}*///JDK1.7泛型的简化,1.6编译通不过List<Fruit> list2 = new ArrayList<>();}
}

参考:

https://segmentfault.com/a/1190000014824002?utm_source=tag-newest

http://www.importnew.com/tag/%E6%B3%9B%E5%9E%8B

Java -- 泛型相关推荐

  1. Java 泛型super和extend

    假设:Men extends Person 但是不能 List<Person> list = new List<Men>(); 会报错! 因为: Men is-a Person ...

  2. java 死锁演示_史上最通俗理解的Java死锁代码演示

    死锁的概念 知识储备 对象锁:Java一切皆对象,每个类都有一个class文件.由class文件可以new出对象,我们简单认识 下java对象,对象有个对象头信息,也就是这个对象概述,其中一条信息就是 ...

  3. Java 泛型 super extends 边界

    1 为什么要用通配符和边界? 使用泛型的过程中,经常出现一种很别扭的情况 比如我们有Fruit类,和它的派生类Apple class Fruit {} class Apple extends Frui ...

  4. 泛型 super和extend

    一:擦除 要理解super和extends的边界问题,首先要理解消除. 先看一个有趣的例子,代码打印结果为true public class Abrasion {public static void ...

  5. java泛型extend使用_java泛型中的? extend E 和 ? super E

    public class TestType { public static void main(String[] args) { //? extend B,在定义泛型时,只能接受B或B的子类 List ...

  6. Java泛型 通配符? extends与super

    本文来源:https://i.cnblogs.com/EditPosts.aspx?opt=1 感谢博主.本文仅供参考学习. Java 泛型 关键字说明 ? 通配符类型 <? extends T ...

  7. Java泛型中extends T和super T的区别?

    <? extends T>和<? super T>是Java泛型中的"通配符(Wildcards)"和"边界(Bounds)"的概念. ...

  8. java中super()_Java 泛型中 extends 和 super 的区别是什么?

    <? extends T> 和 <? super T> 是 Java 泛型中的 "通配符(Wildcards)" 和 "边界(Bounds)&qu ...

  9. Java泛型三:通配符详解extends super

    在java泛型中,? 表示通配符,代表未知类型,< ? extends Object>表示上边界限定通配符,< ? super Object>表示下边界限定通配符. 通配符 与 ...

  10. Java泛型中extends和super的理解(转)

    E – Element (在集合中使用,因为集合中存放的是元素) T – Type(Java 类) K – Key(键) V – Value(值) N – Number(数值类型) ? – 表示不确定 ...

最新文章

  1. 多级嵌套json格式
  2. 如何在Java中验证电话号码(正则表达式+ Google libphonenumber)
  3. python 使用期物处理并发
  4. iOS-Senior20-Map定位
  5. 【Linux】linux和Mac下命令vmstat
  6. Linux中的mce处理--mce学习笔记
  7. 网络工程师Day6--实验3-2 NAT配置
  8. 整理 深入理解RunLoop
  9. 阿里淘系21春招实习过经
  10. 计算机运行一段时间黑屏,电脑运行一段时间之后间歇性黑屏,黑屏一秒钟恢复,过几秒又黑屏,是显卡问题还是cpu问题...
  11. 神通数据库适配 hibernate
  12. 敏捷与CMMI的同与不同
  13. 基于MATLAB车牌识别算法实现 GUI界面
  14. LeetCode--476. 数字的补数
  15. 7-2 哥尼斯堡的“七桥问题” (25分)
  16. 如何简单理解集合框架和利用时空复杂度?
  17. 最小费用最大流 【模板】
  18. 国内各类 WebShell 密码大全 爆破、社工用 webshell-password
  19. wiondows如何更新pip版本
  20. 产品经理需求文档(PRD)怎么写?

热门文章

  1. 《零基础看得懂的C语言入门教程 》——(四)C语言的基本数据类型及变量
  2. 这是你想象中的泳池美女吗?爱了吗?
  3. 分享一个理工男必学的撩妹姿势
  4. 学会了Python之后,我的职业生涯突飞猛进
  5. 这是对R的误解!R的应用原来这么广!
  6. 用python挖一挖知乎上宅男们最喜欢的1000个妹子
  7. java抓取新闻_【图片】【抓取】Java获取各大网站新闻【java吧】_百度贴吧
  8. 计算机应用技术编译原理考试题,《编译原理》练习题库含答案(大学期末复习资料).doc...
  9. ubuntu安装mysql_Ubuntu18.04下安装MySQL
  10. 前端对div连线_《前端图形学从入门到放弃》003 三维世界