定义带泛型的类

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. 基于Docker的ELK日志平台搭建

    1.安装Docker Docker可简单理解为一个轻量级的虚拟机.Docker对进程进行封装隔离,隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器.Docker和传统虚拟化方式的不同.传统虚拟 ...

  2. 在IIS使用localDB

    项目使用localdb来作为本机测试数据库,发布到本机IIS后项目却链接不到数据库,查看windows日志为如下错误 "无法获取本地应用程序数据路径.很可能是因为未加载用户配置文件.如果在 ...

  3. Mac Sublime text3 如何设置更加漂亮好用?

    说明:配置是根据自己的需求搜索了蛮多博客测试总结的. 显示效果 配置信息: command + , [逗号], 右侧配置信息 { "color_scheme": "Pac ...

  4. Mac下安装pymssql

    需要先安装freetds 先用 brew list 查看已经安装的包 如果已经安装freetds,则使用 brew uninstall freetds先卸载 brew unlink freetds b ...

  5. [js高手之路]面向对象版本匀速运动框架

    这篇文章的效果,需要看过以下3篇文章: [js插件开发教程]一步步开发一个可以定制配置的隔行变色小插件 [js高手之路]匀速运动与实例实战(侧边栏,淡入淡出) [js高手之路]打造通用的匀速运动框架 ...

  6. win10安装Tensorflow

    win10安装Tensorflow 前提: 保证你的pip>=8.1版本 否则利用python -m pip install -U pip  进行升级,或下载pip源文件 确定你的显卡是否支持c ...

  7. ubuntu PHP相关操作

    php开启重写模块 vim /etc/apache2/apache2.conf 写入<Directory /阿帕奇的项目目录> AllowOverride All </Directo ...

  8. 【转载】ipcs与Linux共享内存

    一.共享内存相关知识 所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的.由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要 ...

  9. ssh远程登录命令简单实例

    ssh远程登录命令简单实例 ssh命令用于远程登录上Linux主机. 常用格式:ssh [-l login_name] [-p port] [user@]hostname 更详细的可以用ssh -h查 ...

  10. contain_of宏定义

    Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. 实现方式: co ...