定义带泛型的类

public class Cat<T> {
//可以用T定义实例变量
private T name;
//可以用T定义形参
  //构造器没有<>
public Cat(T name){
this.name = name;
}
//可以作为返回值
public T forget(){
System.out.println("我叫啥来着?");
return this.name;
}
public static void main(String[] args){
Cat<String> cat = new Cat<>("阿猫");
System.out.println(cat.forget());
}
}

构造泛型对象可省略类型参数

List<String> list = new ArrayList<>();
//等价于List<String> list = new ArrayList<String>();
//编译器会自己推出后边的类型是String

泛型方法

1.泛型方法可以在普通类或者泛型类

2.类型参数放在修饰符之后,返回值之前

public static <T> void test();

不能在静态变量或者静态方法中使用泛型变量,不能实例化泛型变量

因为泛型是要在对象创建的时候才知道是什么类型的,而对象创建的代码执行先后顺序是static的部分,然后才是构造函数等等。所以在对象初始化之前static的部分已经执行了,如果你在静态部分引用的泛型,那么毫无疑问虚拟机根本不知道是什么东西,因为这个时候类还没有初始化。因此在静态方法、数据域或初始化语句中,为了类而引用泛型类型参数是非法的

public class Entry<k,v>{
//以下2种方式是错误的
private static V value; public static void setValue(V value){}; }

泛型不同类型相同

        List<String> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
System.out.println(list1.getClass() == list2.getClass());

上面的代码返回值是true,因此list1和list2都是List类型,与泛型不泛型无关。

类型通配符(?)

    public void getFamaleCat(List<?> list){
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}

1.当不确定传入的类型时,使用类型通配符?,不要使用List<Object>,当你想要传入一个List<String>作为参数时,程序编译不会通过,而使用?则可以通过

2.当确定类型是某个类的子类型时,使用<? extends Father>,这时传入的类型只能是Father及其子类

public class Util{
/*
方法实现将src中的数据复制到dest中
那么src中的数据类型只能是dest中数据类型的子类型
比如:src中类型是Integer,dest中可以是Integer,Number,Object
*/
public static <T> void copy(List<T> dest,List<? extends T> src){
for(T d : src){
dest.add(d);
}
} public static void main(String[] args){
List<Integer> src = new ArrayList<>();
src.add(1);
src.add(2);
List<Number> dest = new ArrayList<>();
//泛型的匹配方式是直接把参数拿过来和T比
     //因为dest的类型是Number,所以推出T是Number,所以dest集合中的类型都是Number
copy(dest,src);
}
}

3.当确定类型时某个类的父类型时,使用<? super son>,这时传入的类型只能是son及son的父类

上面的例子最后dest中的数据类型都是Number,但是我们清楚的知道其实dest中每个数据的类型都是Integer,使用<? super son>改造

public class Util{
public static <T> void copy(List<? super T> dest,List<T> src){
for(T d : src){
dest.add(d);
}
} public static void main(String[] args){
List<Integer> src = new ArrayList<>();
src.add(1);
src.add(2);
List<Number> dest = new ArrayList<>();
//dest集合中元素都是Integer类型
copy(dest,src);
}
}

4.泛型可以重载,不要包括2个意思相同的泛型方法

 public static <T> void copy(List<? super T> dest,List<T> src);
public static <T> void copy(List<T> dest,List<? extends T> src);

如果我们把这2个方法定义在同一个类里,main调用copy,编译器不能确定到底调用哪个方法

    public static void main(String[] args){
List<Integer> src = new ArrayList<>();
src.add(1);
src.add(2);
List<Number> dest = new ArrayList<>();
copy(dest,src);
}

类型擦除

所有的泛型类型会被编译成一个原始类型

这样并不会不安全

例如:List<String>,因为泛型会在编译的时候起作用,实际上你传入集合的所用元素都只能是String类型

public class Cat<Object> {
private Object name; public Cat(Object name){
this.name = name;
} public Object forget(){
System.out.println("我叫啥来着?");
return this.name;
}
}

JavaSE笔记-泛型的更多相关文章

  1. JAVASE笔记回顾

    第一部分,JAVA基础和面向对象 part01 入门与开发环境搭建 1: 计算机基础知识(了解)(1)计算机(2)计算机硬件(3)计算机软件系统软件:windows,linux,mac应用软件:QQ, ...

  2. Java笔记--泛型总结与详解

    泛型简介: 在泛型没有出来之前,编写存储对象的数据结构是很不方便的.如果要针对每类型的对象写一个数据结构,     则当需要将其应用到其他对象上时,还需要重写这个数据结构.如果使用了Object类型, ...

  3. Java学习笔记--泛型

    一个泛型类就是具有一个或者多个类型变量的类. 我们可以只关注泛型,而不会为数据存储的细节而烦恼 . java泛型(一).泛型的基本介绍和使用 http://blog.csdn.net/lonelyro ...

  4. Java学习笔记——泛型

    假定T不仅要指定接口的类继承.使用下面的方式: public class some<T extends Iterable<T> & Comparable<T>&g ...

  5. Thinking in Java学习笔记-泛型和类型安全的容器

    示例: public class Apple { private static long counter; private final long id = counter++; public long ...

  6. JavaSE笔记-注释

    Annotation Annotation是一个接口,可以把Annotation当成一个修饰符 Annotation的定义 注解通过@interface定义 public @interface Tes ...

  7. .NET复习笔记-泛型

    1.yield关键字用于返回迭代器具体的值,如下框代码所示 /// 返回0~9整数集合 public static IEnumerable<int> yieldSampleMethod() ...

  8. Java 学习笔记 泛型

    泛型 上界匹配 ? extends Number 下界匹配 ? super Number getSimpleName 不包括包名 getName 会包括包名 常和反射联合使用,做框架 Type是一个标 ...

  9. Java笔记——泛型擦除

    1. 泛型擦除 package cn.Douzi.T_Demo; import java.util.ArrayList; /** * @Auther: Douzi * @Date: 2019/3/8 ...

随机推荐

  1. 通过 python的 __call__ 函数与元类 实现单例模式

    简单一句话,当一个类实现__call__方法时,这个类的实例就会变成可调用对象. 直接上测试代码 class ClassA: def __call__(self, *args, **kwargs): ...

  2. 在macOS上通过pyenv安装和切换多版本Python

    1. 安装homebrew 官网 http://brew.sh/index_zh-cn.html 打开终端,在终端中粘贴如下脚本 /usr/bin/ruby -e "$(curl -fsSL ...

  3. Linux系统编程:简单文件IO操作

    使用Linux的文件API,经常看见一个东西,叫做文件描述符. 什么是文件描述符? (1)文件描述符其实实质是一个数字,这个数字在一个进程中表示一个特定的含义,当我们open打开一个文件时,操作系统在 ...

  4. jBPM学习之部署流程定义

    也许部署流程定义的方法有很多,这里选用的是用Java代码调用工作流引擎提供的部署服务API.在这之前,假设你的Eclipse已经安装好了GPD工作流画图工具,并且学会了画出最简单的HelloWorld ...

  5. Anaconda使用

    转自PeterYuan   序 Python易用,但用好却不易,其中比较头疼的就是包管理和Python不同版本的问题,特别是当你使用Windows的时候.为了解决这些问题,有不少发行版的Python, ...

  6. python常用模块详解

    python常用模块详解 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用p ...

  7. docker:(5)利用docker -v 和 Publish over SSH插件实现war包自动部署到docker

    在 docker:(3)docker容器挂载宿主主机目录 中介绍了运行docker时的一个重要命令 -v sudo docker run -p : --name tomcat_xiao_volume ...

  8. Python各类图像库的图片读写方式总结

    最近在研究深度学习视觉相关的东西,经常需要写python代码搭建深度学习模型.比如写CNN模型相关代码时,我们需要借助python图像库来读取图像并进行一系列的图像处理工作.我最常用的图像库当然是op ...

  9. 五分钟学习React(二):我的第一个Hello World

    我的第一个React应用 接着我们上一期所讲的内容,通过create-react-app脚手架创建的应用,它是基于ES6的语法生成的.我们清空src目录下的文件,并分别创建index.js和index ...

  10. Java眼中的XML--------文件读取

     XML 的初次邂逅 初次邂逅XML 如何进行XML文件解析前的准备工作 在Java程序中如何获取xml文件的内容 在Java程序中读取xml文件的过程也成为----解析xml文件 解析的目的:获取节 ...