首页 > 其他分享 >泛型

泛型

时间:2024-04-16 16:37:35浏览次数:21  
标签:val void class 泛型 array public

一. 泛型类、接口

1. 泛型类定义与使用



查看代码
 // <T> 是泛型标识, 相当于 类型形参
// 在外部使用类的时候指定
class Generic<T> {
    private T val;

    public Generic(T val) {
        this.val = val;
    }

    public T getVal() {
        return val;
    }

    public void setVal(T val) {
        this.val = val;
    }
}

class Test {
    public static void main(String[] args) {
        // 这里的 <String> 相当于是实参
        Generic<String> stringGeneric = new Generic<>("abc");
        System.out.println(stringGeneric.getVal());

        Generic<Integer> integerGeneric = new Generic<>(123);
        System.out.println(integerGeneric.getVal());
    }
}

 

泛型类注意点 

泛型类,如果没有指定具体的数据类型,此时,操作类型是Object

泛型的类型参数只能是类类型,不能是基本数据类型

泛型类型在逻辑上可以看成是多个不同的类型,但实际上都是相同类型

 

2. 泛型的作用

1. 编译的时候 检查类型

2. 帮助进行类型转换

查看代码
 // 泛型类
class MyArray<T> {

    public Object[] array = new Object[10];

    public void setValue(int pos,T val) {
        array[pos] = val;
    }

    public T getValue(int pos) {
        return (T) array[pos];
    }

}

class Test {
    public static void main(String[] args) {
        MyArray<String> myArray = new MyArray<>();

        // 泛型的作用1: 编译的时候 检查类型
        // myArray.setValue(1,1);  // 报错 !
        myArray.setValue(0,"abc");

        // 泛型的作用2: 帮助进行类型转换
        String str = myArray.getValue(0); // 不需要强转 
        System.out.println(str);
    }
}

 

3. 泛型类的继承

查看代码
package Generics;

//父类
class Parent<E> {
    private E value;
    public E getValue() {
        return value;
    }
    public void setValue(E value) {
        this.value = value;
    }
}

/**
 * 泛型类派生子类,子类也是泛型类,那么子类的泛型标识要和父类一致。
 * @param <T>
 */

// 子类ChildFirst会把 T类型 当做参数, 传递给父类Parent
// Parent 只有与子类有相同的泛型标识, 才能接收子类传递过来的参数
class ChildFirst<T> extends Parent<T> {

    @Override
    public T getValue() {
        return super.getValue();
    }
}

class Test4 {
    public static void main(String[] args) {
        ChildFirst<String> childFirst = new ChildFirst<>();
        childFirst.setValue("abc");
        String str = childFirst.getValue();
        System.out.println(str);
    }
}

 

查看代码
package Generics.demo2;

class Parent<E> {
    private E value;
    public E getValue() {
        return value;
    }
    public void setValue(E value) {
        this.value = value;
    }
}


// 因为子类没泛型标识, 没办法传递类型给父类
// 所以, 父类要明确数据类型
class ChildSecond extends Parent<Integer> {
    @Override
    public Integer getValue() {
        return super.getValue();
    }
    @Override
    public void setValue(Integer value) {
        super.setValue(value);
    }
}

class Test {
    public static void main(String[] args) {
        ChildSecond childSecond = new ChildSecond();
        childSecond.setValue(123);
        System.out.println(childSecond.getValue());
    }
}

 

 

4. 泛型接口

实现泛型接口的类,不是泛型类,需要明确实现泛型接口的数据类型

查看代码
 interface Generator<T> {
    T getKey();
}

/**
 * 实现泛型接口的类,不是泛型类,需要明确实现泛型接口的数据类型。
 */
class Apple implements Generator<String> {
    @Override
    public String getKey() {
        return "hello generic";
    }
}

class Test {
    public static void main(String[] args) {
        Apple apple = new Apple();
        System.out.println(apple.getKey());
    }
}

 

泛型类实现泛型接口, 要保证实现接口的泛型类泛型标识,包含泛型接口的泛型标识

查看代码
package Generics.demo2;


interface Generator<T> {
    T getKey();
}

// 泛型类实现泛型接口
// 要保证实现接口的泛型类, <T,E> 泛型标识 包含 泛型接口的泛型标识 <T>
class Pair<T,E> implements Generator<T> {

    private T key;
    private E value;

    public Pair(T key, E value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public T getKey() {
        return key;
    }

    public E getValue() {
        return value;
    }
}

class Test {
    public static void main(String[] args) {
        Pair<String,Integer> pair = new Pair<>("num",100);
        System.out.println( pair.getKey() );
        System.out.println( pair.getValue() );

    }
}

 

二. 泛型的上界

class MyArray<T extends Number> {

    public Object[] array = new Object[10];

    public void setValue(int pos,T val) {
        array[pos] = val;
    }

    public T getValue(int pos) {
        return (T) array[pos];
    }

}

class Test {
    public static void main(String[] args) {
        
        // 传入的数据类型必须是 Number类型本身 或者子类
        // 报错 !
        MyArray<String> myArray = new MyArray<>();
        myArray.setValue(0,"abc");

        MyArray<Integer> myArray1 = new MyArray<>();
        myArray1.setValue(1,1);
    }
}

 

// <T extends Comparable<T>> 表示
// 传入的数据类型 必须实现 Comparable接口
class Alg<T extends Comparable<T>> {

    public T findMaxVal(T[] array) {
        T max = array[0];
        for (int i = 1; i < array.length; i++) {
            if(array[i].compareTo(max) > 0) {
                max = array[i];
            }
        }
        return max;
    }
}

class Test {
    public static void main(String[] args) {
        Integer[] array = {1,4,3,8,7,5};
        Alg<Integer> alg = new Alg<>();
        System.out.println(alg.findMaxVal(array));

    }
}

 

三. 泛型方法

class Alg3 {

    // 泛型方法
    public static <T extends Comparable<T>> T findMaxVal(T[] array) {
        T max = array[0];
        for (int i = 1; i < array.length; i++) {
            if(array[i].compareTo(max) > 0) {
                max = array[i];
            }
        }
        return max;
    }
}
class Test {
    public static void main(String[] args) {
        Integer[] array = {1, 4, 3, 8, 7, 5};
        System.out.println(Alg3.<Integer>findMaxVal(array));
        System.out.println(Alg3.findMaxVal(array));
    }
}

 

四. 类型通配符

1. 通配符

查看代码
package Generics.demo2;


import java.util.Objects;

class Box<E> {
    E val;

    public E getVal() {
        return val;
    }

    public void setVal(E val) {
        this.val = val;
    }
}

class Test {

    // 不能传入box2, 因为box2指定的类型为Integer
   /* public static void print(Box<Number> box) {
        System.out.println(box.getVal());
    }*/

    // 类型通配符
    // ? 表示任意类型实参 ex: Number,Integer
    // 一定要注意区分 ? 表示任意类型 实参, 而不是形参 T,K,V
    public static void print(Box<?> box) {
        System.out.println(box.getVal());
    }

    public static void main(String[] args) {
        Box<Number> box1 = new Box<>();
        box1.setVal(1);
        print(box1);

        Box<Integer> box2 = new Box<>();
        box2.setVal(2);
        print(box2);
    }
}

 

2. 类型通配符的上限

查看代码
package Generics.demo2;

class Box<E> {
    E val;

    public E getVal() {
        return val;
    }

    public void setVal(E val) {
        this.val = val;
    }
}

class Test {
    
    // <? extends Number> 表示 传入实参类型, 是 Number本身 或者 Number子类
    public static void print(Box<? extends Number> box) {
        System.out.println(box.getVal());
    }

    public static void main(String[] args) {
        Box<Number> box1 = new Box<>();
        box1.setVal(1);
        print(box1);

        Box<Integer> box2 = new Box<>();
        box2.setVal(2);
        print(box2);
    }
}

 

3. 通配符的下限

查看代码
 package Generics.demo2;

class Box<E> {
    E val;

    public E getVal() {
        return val;
    }

    public void setVal(E val) {
        this.val = val;
    }
}

class Test {

    // <? super Integer> 表示 传入实参类型, 是 Integer 或者 Integer 父类
    
    public static void print(Box<? super Integer> box) {
        System.out.println(box.getVal());
    }

    public static void main(String[] args) {
        Box<Number> box1 = new Box<>();
        box1.setVal(1);
        print(box1);

        Box<Integer> box2 = new Box<>();
        box2.setVal(2);
        print(box2);
    }
}

 

标签:val,void,class,泛型,array,public
From: https://www.cnblogs.com/xumu7/p/18097448

相关文章

  • TS — 泛型
    泛型(Generics)是TypeScript中的一个重要特性,它允许在定义函数、类或接口时使用参数类型的占位符,从而增加代码的灵活性和复用性。1.泛型函数泛型函数允许在函数定义时使用类型参数,这些类型参数可以在函数体内使用,从而使函数可以处理多种类型的数据:functionidentity<T>(arg:......
  • 8.集合、泛型、枚举、注解、反射
    第八章【集合、泛型、枚举、注解、反射】一、集合1、概述集合是JavaAPI中提供的一种容器工具,可以用来存储多个数据。集合框架中主要有三个要素组成:接口实现类数据结构集合中不可以存放基本类型集合按照其存储结构可以分为两大类:java.util.Collection 单值存放......
  • 泛型中的协变和逆变
    协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型。泛型类型参数支持协变和逆变,可在分配和使用泛型类型方面提供更大的灵活性。微软官方解释:https://learn.microsoft.com/z......
  • Java高阶私房菜:探索泛型之妙用
        “泛型”(generics)作为Java特性之一,已经出现较长时间了,相信大家或多或少有接触过,接下来我们将系统重新回顾一下泛型,温故而知新,希望能有些新的启发。Java中的泛型作为V1.5后新增的特性,在JDK源码、中间件源码中有大量的使用,如果掌握了泛型将更容易理解源码,也提升代码抽......
  • 泛型类型参数约束2 - 枚举作为约束类型
    先复习下枚举的相关基础知识:枚举类型(EnumType)说明枚举只有一种成员:命名的整型常量的集合枚举是值类型使用枚举有效地防止用户提供无效值,使代码更加清晰定义枚举:注意:​枚举成员不可以使用修饰符​每个枚举成员底层都是一个常量值​默认情况下,枚举成员的类型是int......
  • 集合和泛型
    usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;//ArrayList的简单例子usingSystem.Collections;//引用集合的命名空间namespaceArryList的简单例子{classProgram{staticvoidMain(string[]args)......
  • Java基础知识总结(第九篇):泛型和JUnit5
    声明:        1.本文根据韩顺平老师教学视频自行整理,以便记忆       2.若有错误不当之处,请指出系列文章目录Java基础知识总结(第一篇):基础语法Java基础知识总结(第二篇):流程控制语句(分支控制和循环控制)Java基础知识总结(第三篇):数组、排......
  • C#泛型详解
    一、什么是泛型泛型是C#2.0推出的新语法,不是语法糖,而是2.0由框架升级提供的功能。我们在编程程序时,经常会遇到功能非常相似的模块,只是它们处理的数据不一样。但我们没有办法,只能分别写多个方法来处理不同的数据类型。这个时候,那么问题来了,有没有一种办法,用同一个方法来处理传入......
  • Java面试题:解释Java泛型的主要用途,并说明泛型擦除的概念。
    Java泛型(Generics)的主要用途是提供一种编写可重用且类型安全的代码的方法。它们允许在编程时使用类型参数,这些类型参数可以在运行时被具体的类或接口替换。泛型的主要优点包括:类型安全:泛型编译时会进行类型检查,确保在运行时使用的是正确的类型,从而减少类型转换错误。代码复......
  • 泛型参数
    demopublicabstractclassAvconBaseServiceImpl<MextendsBaseMapper<T>,TextendsBaseEntity>extendsServiceImpl<M,T>{@AutowiredprotectedMbaseDao;@AutowiredEmsEsDeviceDaoemsEsDeviceDao;protectedLoglo......