java核心:泛型

荆小六      2022-04-30     379

关键词:

一、泛型的目的

  • 泛型解决的是:向下转型时存在的安全隐患;
  • 泛型的核心是:在定义类或接口的时候,不需要显示地声明参数或属性的类型。

二、类中使用泛型

  • 注:在类、接口或方法中,泛型可以定义多个,泛型的名称自定义;
  • 注:使用泛型中,在显示指定具体类型时,只能是引用类型,不能是基本数据类型;
  • 注:使用泛型中,如果没有显示指定具体类型,则系统默认使用Object作为具体类型;
package com.study.Type;

/**
 * 在声明类的时候,定义了两个泛型:T、A
 * @param <T>
 * @param <A>
 */
class Fruit<T, A>{
    private T name;
    private A size;

    public Fruit(T name, A size) {
        this.name = name;
        this.size = size;
    }

    public void getInfo(){
        System.out.println("name: "+this.name+" , size: "+this.size);
    }

    public T getName() {
        return name;
    }

    public void setName(T name) {
        this.name = name;
    }

    public A getSize() {
        return size;
    }

    public void setSize(A size) {
        this.size = size;
    }

}

public class Test {
    public static void main(String[] args) {
        Fruit<String,Integer> f1 = new Fruit<>("苹果",10);
        f1.getInfo();                   // name: 苹果 , size: 10
        String name2 = f1.getName();
        int size2 = f1.getSize();
        System.out.println(name2);      //  "苹果"
        System.out.println(size2);      //  10

        Fruit<String,String> f2 = new Fruit<>("苹果","直径10公分");
        f2.getInfo();                   // name: 苹果 , size: 直径10公分
    }
}

 三、接口中使用泛型

package com.study.Type;

/**
 * 接口使用泛型:T
 */
interface IFruit<T>{
    public void print(T t);
}

/**
 * 实现类继续使用泛型:T
 */
class Apple<T> implements IFruit<T>{
    @Override
    public void print(T t) {
        System.out.println(t+" , "+t.getClass());
    }
}

/**
 * 实现类不使用泛型,指定接口的泛型参数类型
 */
class Orange implements IFruit<String>{
    @Override
    public void print(String s) {
        System.out.println(s+" , "+s.getClass());
    }
}

public class Test {
    public static void main(String[] args) {
        IFruit<String> a1 = new Apple<String>();
        a1.print("苹果");         //  苹果 , class java.lang.String

        IFruit<Integer> a2 = new Apple<Integer>();
        a2.print(100);           //  100 , class java.lang.Integer

        IFruit<String> orange = new Orange();
        orange.print("橘子");     //  橘子 , class java.lang.String
        //orange.print(100);     //语法错误:Error:(43, 22) java: 不兼容的类型: int无法转换为java.lang.String


    }
}

 

四、方法中使用泛型

class Test {
    public static void main(String[] args) {
        String str = print("苹果");
        System.out.println(str);    // 苹果

        int num = print(123);
        System.out.println(num);    //  123
    }

    /**
     * 
     * @param t :   入参
     * @param <T> : 声明一个泛型
     * @return
     */
    public static  <T> T print(T t){
        return t;
    }
}

五、通配符"?"的使用

  • 注:使用通配符,只能取出数据,不能设置数据
package com.study.Type;

import java.util.Date;

    class Message<T> {
   private T msg;

    public Message(T msg) {
        this.msg = msg;
    }

    public T getMsg() {
        return msg;
    }
}


public class Test {
    public static void main(String[] args) {
        Message<String> f1 = new Message<>("苹果");
        print(f1);      //  苹果 , class java.lang.String

        Message<Integer> f2 = new Message<>(100);
        print(f2);      //  100 , class java.lang.Integer

        Message<Date> f3 = new Message<>(new Date());
        print(f3);      //  Fri Mar 08 15:26:25 CST 2019 , class java.util.Date
    }

    /**
     * 使用通配符"?",来接受泛型
     * @param message
     */
    public static void print(Message<?> message){
        System.out.println(message.getMsg()+"  ,  "+message.getMsg().getClass());
    }
}

六、通配符的引申用法

  1、"? extends 类" : 设置泛型上限。可以在声明上和方法参数上使用。

  • 如:"? extends Number":意味着只可以设置Number或Number的子类(如:Integer、Long、Double、......)

  2、"? super 类":设置泛型下限。可以在方法参数上使用。

  • 如:"? super Number":意味着只可以设置Number和Number的父类(Object)

七、分析:泛型

  1、Java泛型只存在于编辑期(.java文件中),在编译成字节码文件(.class文件)时,会把泛型擦除掉,替换为具体的类型

  在JAVA的虚拟机中并不存在泛型,泛型只是为了完善java体系,增加程序员编程的便捷性以及安全性而创建的一种机制,在JAVA虚拟机中对应泛型的都是确定的类型,在编写泛型代码后,java编译过程中会把这些泛型参数类型都擦除,用相应的确定类型来代替,代替的这一动作叫做类型擦除,而用于替代的类型称为原始类型,在类型擦除过程中,一般使用第一个限定的类型来替换,若无限定,则使用Object。

  2、泛型类的静态变量是共享的,于具体实例化的基本类型无关。

 

class GT<T>{
    /**
     * 泛型类的静态变量是共享的
     */
    public static int var = 0;
public void nothing(T x){} } class StaticTest{ public static void main(String[] args){ GT<Integer> g1 = new GT<Integer>(); g1.var = 1; System.out.println(g1.var); // 1 GT<String> g2 = new GT<String>(); g2.var = 2; System.out.println(g1.var); // 2 System.out.println(g2.var); // 2 GT<Date> g3 = new GT<>(); System.out.println(g1.var); // 2 System.out.println(g2.var); // 2 System.out.println(g3.var); // 2 } }

 

 

 

给大忙人看的java核心技术笔记(6泛型编程)

要点:  泛型类是带有一个或多个类型参数的类  泛型方法是带有类型参数的方法  可以要求类型参数必须是一个或者多个类型的子类型  泛型类型是不变得:当S是T的子类型是,G<S>和G<T>没有关系  通过使... 查看详情

关于java核心技术(卷一)读后的思考(泛型数组列表的讨论)

在C++中编译时是要确定数组大小的,而Java有所不同,它允许在运行时确定数组的大小。但是如果仅通过数组是无法改变运行时无法动态更改数组的问题。一旦确定了数组大小,就很难改变他了数组的大小了,要解决这个问题,... 查看详情

泛型-类型擦除

参考:java核心技术一、Java泛型的实现方法:类型擦除前面已经说了,Java的泛型是伪泛型。为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉。正确理解泛型概念的首要前提是理解类型擦出(typee... 查看详情

java开发-泛型实例

JAVA开发过程中经常会涉及到跟踪源码或查看架构师核心代码的活动。在核心代码或源码中常见有<T>,<E>,<K,V>,Class<?>,<?extendsT><?superT>相关的代码。看起来十分高大上,又不容易看懂,可能会吓退一些同学... 查看详情

java核心技术知识点笔记—泛型程序设计(代码片段)

1、泛型方法:(1)定义:泛型方法的定义方式,将类型变量放在修饰符的后面,返回类型的前面。publicclassTestGenericCpublic<T>voidtest(Tt)System.out.print(t);如上,在一个普通类中定义了一个泛型方法。... 查看详情

java泛型相关总结(上)(代码片段)

最近在看《Java核心技术》泛型相关的部分,总结下。泛型程序设计是什么?泛型编程(genericprogramming)是计算机编程中的一种风格,类型通过参数指定。意味着编写的代码可以被不同类型的对象所使用。类型参数(typeparameters)... 查看详情

如何使用泛型类型注册依赖注入? (.net 核心)

】如何使用泛型类型注册依赖注入?(.net核心)【英文标题】:Howtoregisterdependencyinjectionwithgenerictypes?(.netcore)【发布时间】:2019-05-2309:12:43【问题描述】:我在appSettings.json文件中有一个带有多个参数的asp.net核心网络应用程序。... 查看详情

spring(十三)--spring泛型处理(代码片段)

Java5类型接口-java.lang.reflect.TypeJava泛型反射APISpring泛型类型辅助类核心API-org.springframework.core.GenericTypeResolver1.处理类型相关(Type)相关方法resolveReturnType:获取方法返回值的TyperesolveType:2.处理泛型参数类型(ParameterizedType)相关方法r 查看详情

spring(十三)--spring泛型处理(代码片段)

Java5类型接口-java.lang.reflect.TypeJava泛型反射APISpring泛型类型辅助类核心API-org.springframework.core.GenericTypeResolver1.处理类型相关(Type)相关方法resolveReturnType:获取方法返回值的TyperesolveType:2.处理泛型参数类型(ParameterizedType)相关方法r 查看详情

typescript核心篇——函数_this指向—重载—泛型(代码片段)

Typescript核心篇——函数_this指向—重载—泛型this重载泛型this当函数使用到this时,需要在参数中指出this,包括this的类型,而且this必须在函数的第一位this可以不用在接口中声明interfaceIObja:number;b:number;c(a:number):void;click... 查看详情

java-泛型的作用

...承关系的父子类中(接口也是继承的一种)向上转型:其核心目的在于参数的统一上,根本不需要强制类型转换。向下转型:是为了操作子类定义的特殊功能,需要强制类型转换,可是现在存在的问题是:向下转型其实是一种非... 查看详情

现代java服务端开发核心技术栈

现代Java服务端开发核心技术栈现代Java服务端开发核心技术 Java语言基础篇互联网生态下的JavaJava开发工具箱Java基础项目搭建Java数据存储Java数据运算Java程序流程控制Java数组Java面向对象程序设计Java异常处理Java枚举Java注解Java... 查看详情

现代java服务端开发核心技术栈

现代Java服务端开发核心技术栈现代Java服务端开发核心技术 Java语言基础篇互联网生态下的JavaJava开发工具箱Java数据存储Java数据运算Java程序流程控制Java数组Java面向对象程序设计Java异常处理Java枚举Java注解Java泛型Java集合JavaI... 查看详情

java从toarray返回object[]到泛型的类型擦除

...是泛型类型的数组,而是Object[]。刚好最近翻了一遍《java核心技术》,以及参考《ThinkinJava 查看详情

java基础核心面试问题分析(持续更新)(代码片段)

文章目录JAVA编程基础如何理解面向对象编程?JDK和JRE有什么区别?如何理解Java中封装,继承、多态特性?如何理解Java中的字节码对象?你是如何理解Java中的泛型的?说说泛型应用在什么场景呢?如何... 查看详情

我们如何在不使用泛型类型进行自定义的情况下处理身份核心用户管理和用户存储的多个用户使用情况?

...我们如何在不使用泛型类型进行自定义的情况下处理身份核心用户管理和用户存储的多个用户使用情况?【英文标题】:Howcanwehandlemorethanoneuserusageforidentitycoreusermanagementanduserstorewithoutcustomizationwithgenerictype?【发布时间】:2021-03-0... 查看详情

java——泛型(代码片段)

文章目录Java中泛型的概述Java中泛型的语法规则泛型集合泛型方法泛型方法示例(代码演示)小结泛型类泛型类示例(代码演示)小结泛型接口泛型接口示例(代码演示)高级泛型总结Java中泛型的概述泛型... 查看详情

java泛型:泛型

一、二、三、四、五、六、七、八、  查看详情