首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么泛型类型参数说"扩展"可比较而不是"实现"?

泛型类型参数中的"扩展"可比较而不是"实现"的原因是因为Java编程语言中的泛型机制的限制。在Java中,泛型类型参数可以是类或接口,但是在Java中,类和接口的继承关系是分开的。因此,Java使用"扩展"来表示类之间的继承关系,而使用"实现"来表示接口之间的继承关系。

在Java中,泛型类型参数的类型必须是可比较的,以确保在泛型类型参数中使用的类型是可比较的。如果泛型类型参数使用了"实现"来表示接口之间的继承关系,那么泛型类型参数可能会包含不可比较的类型,这会导致编译错误。因此,Java使用"扩展"来表示类之间的继承关系,以确保泛型类型参数中使用的类型是可比较的。

例如,如果泛型类型参数使用"实现"来表示接口之间的继承关系,那么以下代码可能会导致编译错误:

代码语言:java
复制
public class MyClass<T extends Comparable<T>> {
    public boolean compare(T t1, T t2) {
        return t1.compareTo(t2) == 0;
    }
}

public class MyString implements Comparable<String> {
    @Override
    public int compareTo(String o) {
        return 0;
    }
}

public class MyInteger implements Comparable<Integer> {
    @Override
    public int compareTo(Integer o) {
        return 0;
    }
}

MyClass<MyString> myStringClass = new MyClass<>();
MyClass<MyInteger> myIntegerClass = new MyClass<>();

myStringClass.compare(new MyString(), new MyString()); // 正常
myIntegerClass.compare(new MyInteger(), new MyInteger()); // 正常
myStringClass.compare(new MyString(), new MyInteger()); // 编译错误

在这个例子中,MyStringMyInteger都实现了Comparable接口,但是它们实现的是不同的接口,因此它们是不可比较的。如果泛型类型参数使用"实现"来表示接口之间的继承关系,那么MyClass中的compare方法将无法比较MyStringMyInteger类型的对象,导致编译错误。

因此,Java使用"扩展"来表示类之间的继承关系,以确保泛型类型参数中使用的类型是可比较的。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

in authors } // 这个 扩展函数 能任何种类元素的列表上调用 // val List.penultimate: T //...String 代替 override fun get(index: Int): String = "" } // 现在 ArrayList 的类型...调调用带实化类型参数函数的时候使用非实化类型作为类型实参 * - 把类、属性或者非内联函数的类型参数标记为reified */ 9.3 变型:很子类型化...* 例如,Int类是Number的子类,因此Int类型是Number类型的子类型。 * * 类型 的子类型和子类不是同一事物。...变型是一种说明两种拥有相同基础类型和不同类型参数的类型之间子类型化关系的方式,它说明了如果其中一个类型类型参数是另一个的类型参数的子类型 这个类型就是另外一个类型的子类型或者超类型

1.8K10

你不知道的 TypeScript (万字长文,建议收藏)

如果你不是特别了解,那么你很可能不仅不会用,不会实现,甚至看不懂这是在干什么。...: T[P] }; ❝刚才说了“由于是形,因此起什么名字无所谓” 。因此这里就起了 T 不是 Type,更短了。这也算是一种约定俗称的规范,大家一般习惯叫 T, U 等表示的形。...对应的是 TS 实现的一套标准。 ? ? 简单来说,将类型看成值,然后对类型进行编程,这就是的基本思想。...改成这样是 ok 的: type Lucifer = LeetCode; 为什么使用尖括号 为什么要用尖括号(),不是别的?...虽然支持函数的嵌套,甚至递归,但是其语法能力肯定和 JS 没法比, 想要实现一个功能真的不是一件容易的事情。

2.3K30
  • 2.1.3 的适用范围 并非所有类型或者类型成员都适用。对于类型,这很好区分,因为可供声明的类型比较有限:枚举不能声明为类、结构体、接口以及委托这些可以声明为类型。...对于类型成员来说,就没那么界限分明了。有些类型成员因为使用了其他类型,看似成员,但实际不是。只需记住一条原则:判断一个声明是否是声明的唯一标准,是看它是否引入了新的类型。...对于这些无法声明为类型成员,通常很难想象出它们如何才能成为。有时我也有编写构造器或者索引器的需求,最后往往是用一个方法就实现了同样的功能。...直接调用构造器的实现代码比较烦琐:new Tuple(10, "x", 20) 但是使用静态方法配合类型推断,代码就简单多了4:4前面说过构造器不能为,构造器中的参数实际上是来自它所在类的类型...C# 2加入了default()运算符,并且略微扩展了typeof的用途。default运算符的功能比较简单:它是一元运算符,其操作数是类型名或类型,返回值是该类型的默认值。

    1.4K10

    【数据结构】包装类和

    当你创建Integer类型的对象时,(使用.valueOf或自动装箱来创建对象,) 如果值在这个范围内,Java会直接从内存中返回已经存在的对象,不是创建新对象。...a和b指向同一个对象,因此 a==b结果为true; aa和bb指向的不是同一个对象,因此 aa==bb结果为false。 通俗讲,就是适用于许多类型。...⭐语法 基本类定义: class 类名称 { // 这里可以使用类型参数 } 这里的类名称是类的名称就,是定义在尖括号中的类型参数列表,它们是占位符...Java的机制是在编译级别实现的,因此编译器生成的字节码文件中不包含类型信息。...,实现了这个接口后, 这个类的对象可以与其它同类型的对象进行比较

    6510

    Kotlin入门潜修之类和对象篇—及其原理

    首先说下的概念,所谓即是类型的参数化。怎么理解呢?想一下以前我们所说的方法,如果方法有入,那么这些入前面往往会有类型,这个类型就是为了修饰参数所用。...因为map2的值只能是Integer,所以返回的是Integer,不是String } java中既支持类也支持方法。...extends E> c); 我们发现addAll方法入定义实际上是这个类型不是这个类型。这就引出了java中的通配符(使用?表示)概念。...注释已经比较详细,主要描述了通配符的应用场景。结合上面代码我们可以总结如下: 1.对于赋值操作(参数入也是赋值的一种情形)。...错误,需要Array类型,但是传入的是Array类型 } 上面的代码又复现了经典的问题,即类型是不变因子,即Array不是Array的子类,为什么要这么限制?

    92830

    Go 发展史与基本介绍

    说白了就是将算法与类型解耦,实现算法更广泛的复用。 四、为什么需要 举个简单的例子。...在这篇叫“窘境”的文章中,Russ Cox 提出了 Go 实现的三个遵循的方法,以及每种方法的不足,也就是三个 slow(拖慢): 拖慢程序员:不实现,不会引入复杂性,但就像前面例子中那样...在这份新技术方案中,Go 团队放弃了引入 contract 关键字作为类型参数的约束,采用扩展后的 interface 来替代 contract。...当我们使用Point类型的值调用Scale(其基础类型为[]int32)时,我们返回的是[]int32类型的值,不是Point类型。这源于代码的编写方式,但这不是我们想要的。...也就是说,为什么我们可以写 Scale(p, 2),没有类型参数,不是必须写 Scale[Point, int32](p, 2) ? 新 Scale 函数有两个类型参数——S 和 E。

    20710

    java边界

    需要注意的一点是,不支持协变(Covariant),协变需使用通配符。为什么不支持协变呢。我们先从支持协变的数组开始考虑。...其主要用处之一是在使用Java或第三方的API的类时,对类型不同,但具有继承关系,且主要关注其输入的对象进行归纳。...输入输出类型能是什么则是根据边界的含义得出的,其中的限制是由于我们只能通过边界对实际类型进行猜测产生的,希望大家能仔细理解其中的含义。 ...在虚拟机看来,List这个类型只是普通的类型List而已,这种行为叫擦除(Type Erasure)。   那么在Java中是如何如何实现其目的的呢?Java的充分利用了多态性。...并在相应的地方自动生成checkcast字节码进行类型检查和转换,这样就既可以实现,又不需要在字节码层面的进行改动来支持。这样的叫做伪

    2K10

    那些年我们在Java上躺过的枪---万恶的擦除【享学Java】

    C++里的是真实的,它通过类模版的概念去实现 初识 (generics),从字面的意思理解就是化的类型,即参数化类型。...方法的声明和类的声明略有不同,它是在返回类型之前用尖括号列出类型参数列表(也可以有多个类型),函数传入的形类型可以利用来表示。...这里就要说到Java语言实现所独有的——擦除。...从上例可以知道,java的擦除确实给实际编程中带来了一些不便(特别是运行时反射时,有时候无法判断出真实类型)。那Java的设计者为什么要这么干呢?...这么看来它和我们上面定义的doSomething(T... values)方法何其相似,因此此处我就不再用代码示例了,总结出下面几条结论即可,具体缘由我建议小伙伴一定要做到心知肚明: 传递的数组必须是对象数组,不是基本类型

    98130

    Kotlin 类型参数约束

    为什么需要类型参数约束在上一篇文章里,我们使用定义了一个列表List,使用这个列表,我们可以在使用的时候,实例化出各种具体类型的列表,比如字符串列表List、整型列表List...中的属性也同样变得空,这使得类在具体实现的时候,需要考虑参数为空的情况,也让编写代码的具体实现变得复杂。...理解了它们的区别,就能明白为什么同样是基于 JVM 字节码,Kotlin 能在 Java 的基础之上实现更严格的空/非空特性, Groovy 却反其道做成了一门动态类型的语言。...本质上「类型」是一个存在于编译过程的「逻辑」概念,「类」则是存在于字节码的「物理实体」。回过来说范。...当我们定义一个范类/范型函数时,由于「类型参数」在被「类型实参」替换时可使用「类型」和「非空类型」这两种类型,这会迫使我们在做具体实现要考虑类型,带来了不必要的复杂性。

    2.3K31

    C# 发展历史及版本新功能介绍

    可以创建自己的接口、类、方法、事件和委托。 可以对类进行约束以访问特定数据类型的方法。 在数据类型中所用类型的信息可在运行时通过使用反射来获取。...通过命名实参,你可以为特定形指定实参,方法是将实参与该形的名称关联,不是与形在形列表中的位置关联。 通过可选参数,你可以为某些形省略实参。...使用命名参数和可选参数时,将按实参出现在实参列表(不是列表)中的顺序计算这些实参。 命名形和可选形一起使用时,你可以只为可选形列表中的少数形提供实参。...Invariance 这意味着,你只能使用原始指定的类型;固定类型参数既不是协变类型,也不是逆变类型。...协变和逆变提供了更强的功能来使用,但风格比较偏学术,应该最受框架和库创建者的喜爱。 命名参数和可选参数帮助消除了很多方法重载,让使用更方便。 但是这些功能都没有完全改变模式。

    4.2K20

    2.7w字!2021 最新版!Java基础面试题知识点总结!(上)

    的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。 Java 的是伪,这是因为 Java 在编译期间,所有的信息都会被擦掉,这也就是通常所说类型擦除 。...:类、接口、方法。...包装类型不赋值就是 Null ,基本类型有默认值且不是 Null。 另外,这个问题建议还可以先从 JVM 层面来分析。...的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。 Java 的是伪,这是因为 Java 在编译期间,所有的信息都会被擦掉,这也就是通常所说类型擦除 。...包装类型不赋值就是 Null ,基本类型有默认值且不是 Null。 另外,这个问题建议还可以先从 JVM 层面来分析。

    80600

    阿里云大神亲码“Kotlin深度笔记”,不讲一句废话,全是精华

    Kotlin 不是一门学问,而是一套工具,它不像Scala,没有那么重的书卷气,一切特性都为实用、简洁而生; Kotlin 不是革命者,而是改良者,它不是 Go,没有取天下代之的野心,只有“让 Java...、包、控制流、返回与跳转 image.png 3.类和对象 主要内容:类和继承、属性和字段、接口、可见性修饰词、扩展、数据对象、、嵌套类、枚举类、对象表达式和声明、代理模式、代理属性 4.函数和lambda...为什么要引入 Lambda 和 高阶函数? 带接收者(Receiver)的函数类型:A....(B,C) -> D HTML Kotlin DSL 实战 image.png Kotlin 遥控器的故事: 招聘的故事:的不变性(Invariant) 搞定招聘:的协变(Covariant...) 填志愿的故事:的逆变(Contravariant) 使用处变(Use-site Variance) Kotlin 实战 Kotlin 扩展 扩展是什么?

    1.1K10

    Java基础不简单,很重要!

    为什么使用 一般我在思考这种问题时,会反过来思考,假如没有会怎么样?...Java 擦除是 Java 中的一个重要特性,其目的是避免过多的创建类造成的运行时的过度消耗。 的使用方式 在上文也提到有三种使用方式:类、接口、方法。...public T next() { return null; } } 当实现接口传入实参时,当参数传入了具体的实参后,则所有使用到的地方都会被替换成传入的参数类型。...代替具体的类型实参,这里的 ? 是具体的类型实参,不是类型。它跟Integer,Double,String这些类型一样都是一种实际的类型,我们可以把 ? 看作是所有类型的父类。...拓展性强,可以使用通配符定义,不需要定义实际的数据类型。 提高了代码的重用性。可以重用数据处理算法,不需要为每一种类型都提供特定的代码。

    24010

    数栈技术分享前端篇:TS,看你哪里逃~

    否则将会 Enum member must have initializer. 11) 笔者理解的很白话:先不指定具体类型,通过传入的参数类型来得到具体类型 我们从下述的 filter-demo...入手,探索一下为什么一定需要 的基础样式 function fun(args: T): T { return args } 如果没接触过,是不是会觉得有点懵?...这个时候如果还是选择重载,将会大大提升工作量,代码也会变得越来越累赘,这个时候就出场了, 它从实现上来说更像是一种方法,通过你的传来定义类型,改造如下: declare function filter...,也可以。...关于TS的底层实现,这个部分比较复杂,笔者还需沉淀,欢迎各位直接留言或在文章中补充!!! ​

    2K30

    面试常考问题:Java的底层原理是什么?

    具体是,需要根据类字节码,获取特定方法名的方法入,此方法名在源码中只有一个。但是在实际使用中发现:在类实现接口的情况下,在字节码层面,类却有两个同名方法,导致无法确定哪个方法才是我们需要的方法。...比如,我们有一个操作算子接口 Operator,接口中有一个 process(T t) 方法,其作用是对入 T 进行逻辑处理。...那么为什么编译器会产生桥接方法呢?以及在什么情况下,会产生桥接方法?以及如何判断一个方法是不是桥接方法?我们继续往下分析。...读者自行测试。 解决方案 通过以上的案例描述,我们知道,在实现接口的场景下,编译器会自动生成桥接方法,保证编译能够通过。...当我们不改变 Child#test() 方法的返回类型时,编译器并没有为我们生成桥接方法,读者自行试验。 也就是说,在子类方法重写父类方法,返回类型不一致的情况下,编译器也为我们生成了桥接方法。

    1.4K12

    数栈技术分享前端篇:TS,看你哪里逃~

    否则将会 Enum member must have initializer. 11) 笔者理解的很白话:先不指定具体类型,通过传入的参数类型来得到具体类型 我们从下述的 filter-demo...入手,探索一下为什么一定需要 的基础样式 function fun(args: T): T { return args } 如果没接触过,是不是会觉得有点懵?...这个时候如果还是选择重载,将会大大提升工作量,代码也会变得越来越累赘,这个时候就出场了, 它从实现上来说更像是一种方法,通过你的传来定义类型,改造如下: declare function filter...,也可以。...关于TS的底层实现,这个部分比较复杂,笔者还需沉淀,欢迎各位直接留言或在文章中补充!!!

    2.7K10

    三分钟, 让你学会 Go

    笔者也很想吐槽:对 Go 的定义,借用了 interface{} 这个关键字。但是与真正的 “接口” 不同的是,“接口” 的定义内容是函数,类型的定义内容是数据类型。...,函数的出也是一个 N,这表示函数的出参与入类型相同,都是 Number 类型。...但是,如果每次我定义一个数字类型的时候都要写这么一长串总归不是个事儿。... Go 的也可以用来修饰类型。最典型的用法,就是用来声明一个 “集合” 类型。...目前 Go 还并不能达到玩出花的程度,也有更多的 Go 提案,各位可以多看看~~扩展阅读:Go 提案Go不支持方法,这是一个悲伤的故事---本文章采用 知识共享署名-非商业性使用-相同方式共享

    833100

    2.7w字!Java基础面试题知识点总结!(2021 最新版)

    什么是类型擦除?介绍一下常用的通配符? Java (generics)是 JDK 5 中引入的一个新特性, 提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。...的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。 Java 的是伪,这是因为 Java 在编译期间,所有的信息都会被擦掉,这也就是通常所说类型擦除 。...:类、接口、方法。...1.类: //此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示 //在实例化类时,必须指定T的具体类型 public class Generic{ private...包装类型不赋值就是 Null ,基本类型有默认值且不是 Null。 另外,这个问题建议还可以先从 JVM 层面来分析。

    54420

    面试系列之-JAVA剖析(JAVA基础)

    一、概述 1. 什么是为什么要使用,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形列表,普通方法的形列表中,每个形的数据类型是确定的,变量是一个参数。...即我们希望当我们向集合中添加了不符合类型要求的对象时,编译器能直接给我们报错,不是在程序运行后才产生异常。这个时候便可以使用了。...,原类可以想象它会自动扩展,其类型参数会被替换。...那为什么还需要引入上界统配符的概念?---- 答:是为了拓展方法形类型参数的范围。...这是上一道题的延伸,面试官可能会要求你用编写一个类型安全的类,不是编写一个方法。关键仍然是使用类型来代替原始类型,而且要使用 JDK 中采用的类型占位符。

    35620
    领券