在 Kotlin 中扩展 Java 类时继承的平台声明冲突

     2023-04-15     44

关键词:

【中文标题】在 Kotlin 中扩展 Java 类时继承的平台声明冲突【英文标题】:Inherited platform declarations *** when extending a Java class in Kotlin 【发布时间】:2018-02-09 00:52:05 【问题描述】:

我正在尝试使用 Kotlin 扩展第三方 Java 类,但我收到以下编译器消息:

继承的平台声明冲突:以下声明具有 相同的 JVM 签名(setCollection(Ljava/util/Collection;)V):

fun setCollection(collection:(Mutable)Collection!: KotlinClass 中定义的单元

fun setCollection(collection:(Mutable)Collection!):KotlinClass 中定义的单位

无论我做什么,都无法仅使用 Kotlin 代码对其进行编译。

重现情况的代码:

//JavaInterface.class
import java.util.Collection;

public interface JavaInterface 
    void setCollection(Collection<String> collection);


//JavaBaseClass.class
import java.util.Collection;

public class JavaBaseClass 
    public void setCollection(Collection collection)


//JavaSubClass.class
public class JavaSubClass extends JavaBaseClass implements JavaInterface 

//KotlinClass.kt
class KotlinClass : JavaSubClass() 

Java 本身没有这个问题。所以我的猜测是这可能与平台类型有关(String! 不是Any?)。

对于这个问题,是否有一个不涉及编写 Java 代码的优雅解决方法?还是应该在 Kotlin 编译器本身内解决这个问题?

【问题讨论】:

【参考方案1】:

我没有详细了解 java 如何/为什么在您的 JavaSubClass 中工作,即它会产生什么字节码,但从 Kotlin 的角度来看,如果我查看这两种方法的签名,它们的调度会模棱两可。

这个:

public void setCollection(Collection collection)

被视为设置泛型类型 Any? 的集合的方法。 任何?是 String 的超集。

如果你班的客户有以下情况:

myCollection = Array<String>()
myInstanceOfKotlinClass.setCollection(myCollection)

应该分派哪个方法?

出于这个原因,我认为这不是 Kotlin 编译器中的错误,而是对一些较松散的 java 泛型类型安全性的改进。显然,java 会选择如何将这两种方法编译到字节码中的同一个类中,如果您知道在上述情况下将选择哪个方法进行分派,那么这是一个不错的方法。但我认为你应该能够仅从签名中分辨出哪一个,而不是一些内部知识。

恐怕我正在努力寻找一种解决方法来为您提供该类型的扩展 kotlin 类。因此,如果您想为该 java 类添加更多功能,并且不需要任何额外的实例状态,您可以尝试使用扩展函数吗?

fun JavaSubClass.newFunctionality()

感觉就像您使用的第三方代码在使用泛型和继承方面做得很差。不过,无论哪种方式,如果您需要更改现有功能的行为或拥有新功能的实例状态,我认为您在处理 Java 领域的这种歧义时会遇到困难,因为我认为 Kotlin 不同意它作为一个原则问题。

编辑:

看java,这个

//JavaSubClass.class
public class JavaSubClass extends JavaBaseClass implements JavaInterface 

暗示JavaBaseClass实现了接口......

它拓宽了接口的通用类型。讨厌的类型擦除错误迫在眉睫。我的意思是看看这个:

import java.util.ArrayList;

public class Main 

    public static void main(String[] args) 
        JavaSubClass sc = new JavaSubClass();
        ArrayList<Integer> myCollection = new ArrayList<>();
        sc.setCollection(myCollection);
    

哎呀。

【讨论】:

我明白你的意思。如果误用,这将导致运行时异常。显然,除了 Kotlin 之外的每个人都在玩这毕竟不是那么糟糕,因为它增加了类型安全性。谢谢你的解释。

继承基础

...要继承(1)代码的复用延续父类的一些特性(2)代码的扩展扩展父类没有的一些特性(3)表示is-a的关系2.如何实现继承?在声明一个类时取继承其父类。语法格式:【修饰符】class子类名extends父类名子类(Subclass):又称为派... 查看详情

kotlin初学者继承(extend)(代码片段)

Kotlin继承(extend)        Kotlin允许一个类继承自另一个类        Kotlin中所有类都继承自Any类        Any类是所有类的超类,对于没有超类型声明的类是默认超类        Kotlin类默认都是封闭的,要让某个类... 查看详情

kotlin与java有什么区别(最全最新的)

目录什么是Kotlin?什么是Java?主要区别:Kotlin的特点Java的特点Kotlin的历史JAVA的历史Kotlin和Java的区别Kotlin的优势Java的优势Kotlin的缺点Java的缺点哪个更好?大家好,我是坚果,这里是坚果前端小课堂,... 查看详情

在kotlin中使用带有rxjava的密封类时,类型不匹配(代码片段)

我有以下代码sealedclassAddressUiStateobjectAddressLoading:AddressUiState()classAddressLoadedState(valaddressResponse:AddressBookResponse):AddressUiState()classAddressErrorState(valerror:Throwable):AddressUi 查看详情

kotlin学习之路:继承(代码片段)

...承二.继承中的构造函数2.1继承中Java的构造函数2.2继承中Kotlin的构造函数2.3Kotlin多个构造函数的情况三.重写和重载3.1方法的重写3.2属性的重写四.super关键字4.1简单用法4.2复杂情况下的用法4.2.1子类重写方法中使用super4.2.2子类选择... 查看详情

kotlin和java区别

参考技术AKotlin是JetBrains开发的基于JVM的语言;而Java是一种可以编写跨平台应用软件、完全面向对象的程序设计语言。Kotlin是对Java的一种改进,语法差异:Kotlin中的方法和属性可以不包含在类中;Java中的一切是以class为基础的,... 查看详情

java中子类继承父类时是否继承构造函数

来源:http://www.cnblogs.com/sunnychuh/archive/2011/09/09/2172131.html---------------------java继承中对构造函数是不继承的,只是调用(隐式或显式)。以下是例子: publicclassFatherClass{ publicFatherClass(){   &nb 查看详情

Java 继承:被覆盖或隐藏的方法

...ods【发布时间】:2012-07-2801:05:09【问题描述】:当一个类扩展另一个类时,它会继承超类的所有方法和变量。如果您在具有相同签名的子类中以不同方式定义方法和变量,则可以在子类中以不同方式使用。现在Oracle区分了覆盖和... 查看详情

在 kotlin REPL 和暂存文件中使用 json 类时出错

】在kotlinREPL和暂存文件中使用json类时出错【英文标题】:ErrorwithusingjsonclassesfromwithinkotlinREPLandscratchfiles【发布时间】:2020-05-1522:11:47【问题描述】:我正在开发一个需要处理从WebAPI检索到的json数据的Android项目。在项目中,我... 查看详情

“独占”继承:对某些形式的多重继承的要求

...ava(或任何其他流行语言)中有没有办法限制哪些类可以扩展/继承给定的类?具体来说,是否可以在扩展某个类时强制执行特定的多重继承模式?我将这篇文章命 查看详情

kotlin中扩展函数和infix关键字详解(代码片段)

...展可以用于自定义类,也可以用于比如List,String,以及Kotlin标准库里的其他类。和继承相似,扩展也能共享类行为,在你无法接触某个类定义,或者某个类没有使用open修饰符,导致你无法继承它时,扩展就... 查看详情

使用 super 关键字的 Java 继承

...描述】:我在我的程序中使用继承和超级函数,但是当我扩展我的类时,它显示错误消息“\'cc\'中没有默认构造函数。”。此错误消息是在扩展第一个子类并尝试创建第二个子类之后出现的。这是代码classaainti=-1;intshow()returni;clas... 查看详情

如何在 Kotlin 中用继承的类覆盖方法?

】如何在Kotlin中用继承的类覆盖方法?【英文标题】:HowtooverridemethodwithinheritedclassinKotlin?【发布时间】:2022-01-1209:16:14【问题描述】:我正在探索并积极在Kotlin的生产环境中使用泛型。Kotlin+泛型对我来说是一个很大的难题,所... 查看详情

kotlin的构造函数看这一篇就够了(代码片段)

在kotlin中,一个标准的继承写法是这样的classAA:BB(),你想过没有,为什么AA后面没有括号,而BB后面有呢?Kotlin和Java中有这样两个特性:1.子类继承父类时,需要在构造函数中调用父类的构造函数2.如果... 查看详情

kotlin小悟-这个继承有点不一样(代码片段)

今天聊聊kotlin中关于构造函数的一个话题。我们知道,在kotlin中构造函数分为主构造函数和从构造函数,关于详细的内容,可以点击下面的文章链接了解。Kotlin系列之主构造方法和初始化语句块Kotlin系列之从构造方法... 查看详情

kotlin学习笔记之面向对象(代码片段)

...ff0c;使用interface表示,示例代码:与java一样,kotlin定义类时要遵循单继承多实现的原则(即只能继承一个父类,可以实现多个接口)kotlin中定义的类和方法默认都是final的,不可重写,如果要实现重... 查看详情

在处理单独的 .cpp 和 .h 文件中的类时,实现继承的正确方法是啥?

】在处理单独的.cpp和.h文件中的类时,实现继承的正确方法是啥?【英文标题】:Whatisthecorrectwaytoimplementinheritancewhendealingwithclassesinseparate.cppand.hfiles?在处理单独的.cpp和.h文件中的类时,实现继承的正确方法是什么?【发布时间... 查看详情

kotlin——集合

参考技术AKotlin的集合类由两个接口派生:Collection和Map。Collection和Map是Java集合框架的根接口,这两个接口又包含一些子接口或实现类Java中的集合都是可变集合,但Kotlin的集合被分为两大类:可变集合和不可变集合。Kotlin也提供... 查看详情