JavaSE笔记-泛型

定义带泛型的类

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;
    }
}

原文地址:https://www.cnblogs.com/vshen999/p/8361453.html

时间: 2024-07-30 09:12:57

JavaSE笔记-泛型的相关文章

【史上最强JavaSE笔记】之数组篇

各位程序猿,各位攻城狮,各位蜥蜴鸥以及各位棕鲸鲤们~~大家好,我是潘师傅,欢迎大家收看由我为你们带来的[史上最强JavaSE笔记]系列,其实也可以叫[嘻哈JavaSE笔记]的,第一次在博客园发帖,想想还真是有点小激动呢,各位求支持呀,哈哈,那么回归正题,我把自己之前学习积累的笔记拿出来跟大家分享一下,方便大家更好的理解和复习,希望能够对大家有所帮助哈,这次发的是JavaSE方面数组篇的,内容不一定全面哦,欢迎大家前来留言交流哈,不足的地方还望大家多多指出和指导哈~(由于首次发文章,布局可能比较乱

JAVASE笔记回顾

第一部分,JAVA基础和面向对象 part01 入门与开发环境搭建 1: 计算机基础知识(了解)(1)计算机(2)计算机硬件(3)计算机软件系统软件:windows,linux,mac应用软件:QQ,YY,扫雷,CS/F(4)软件开发就是用开发工具和计算机语言做出软件(5)计算机语言人与计算机的交流方式(6)人机交互A:图像界面方便,简单,直观.B:DOS 窗口方式要有控制台, 要记住很多的命令, 麻烦.(7)键盘功能键和快捷键的介绍(掌握)A:键盘功能键tabshiftctrlalt空格ent

swift学习笔记-&gt;泛型

如果学过java就知道泛型是什么  比如说定义一个数组  var a : [Int] Int 就是该数组的泛型 创建一个字典也是根据泛型储存内容的 var a : Dictionary <String,String> 而泛型能解决的问题  就像字典一样  他是个不确定的键值对  你定义什么类型就能存什么类型 泛型函数 下面举个例子一个函数  要将两个参数值互换 func myswap(inout a: Int,inout b: Int) { let temp = a a = b b = tem

C#学习笔记 ----泛型

泛型的优点和缺点: 性能 类型安全 二进制代码的重用 代码的扩展 命名约定(字母T作为前缀) 创建泛型类型,如下: public class LinkedListNode<T> { public LinkedListNode(T value) { this.Value = value; } public T Value{get;private set;} public LinkedListNode<T> Next{get;internal set;} public LinkedLi

Java学习笔记——泛型

如果T既要继承类又要指定接口,使用下面方式: public class some<T extends Iterable<T> & Comparable<T>>{} Java的泛型不具有共变性(如果B是A的子类,而Node<B>可视为一种Node<A>,则称Node具有共变性),不过可以使用类型通配字符?与extends来声明变量,使达到类似的共变性. Node<Apple> apple = new Node<>(n

Java笔记--泛型

1.泛型解决元素存储的安全性问题:解决获取数据元素时,需要类型强转的问题. --泛型的核心思想:把一个集合中的内容限制为一个特定的数据类型. 2.泛型的使用 1)在集合中使用 2)自定义泛型类.泛型接口.泛型方法 3)泛型与继承的关系 4)通配符 3.若泛型类.泛型接口没有使用泛型,则默认为Object类型. 4.继承泛型类或泛型接口时,可以指明泛型的类型. 5.泛型方法的定义: public <E> E getE(E e){ return e; } 6.类A是类B的子类,但是List<

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

泛型简介: 在泛型没有出来之前,编写存储对象的数据结构是很不方便的.如果要针对每类型的对象写一个数据结构,     则当需要将其应用到其他对象上时,还需要重写这个数据结构.如果使用了Object类型,编写的数据结构虽然     通用性很好,但是不能保证存入的对象的安全性. --支持知识共享,转载请标注地址"http://www.cnblogs.com/XHJT/p/3958036.html  "——和佑博客园,谢谢~~-- 代码实例1: 不用泛型实现栈结构     1.用Object和

学习笔记——泛型

泛型的意义:泛型用来保证类型的统一,主要目的之一就是用来指定容器要持有什么类型的对象,而且由编译器来保证类型的正确性.1.类型安全,通过设置泛型,可以让编译器验证类型2.消除强制转换.如果不用泛型,将元素从容器中取出时,都是由object类型向目标类型强制转换.而由于泛型的擦除,所有的泛型类型变量都会被替换为原始类型,在获取的时候,集合会实现变量的强制转换,转换是隐式的. 泛型类:public class Test<T> 泛型接口:public interface Generator<T

JavaSE笔记-异常

Java 异常 Throwable类的体系结构(一些常用的) 异常分类 checked,unchecked 区分:RuntimeException及其子类,Error类及其子类,是unchecked 除此之外继承自Exception的异常是checked checked异常在编译时必须处理 关键字 try,catch,finally,throw,throws finally:常用于回收物理资源(数据库连接,网络连接,磁盘文件),finally一定被执行,所以不要在finally中使用return