java - 如何让 Kotlin 停止将参数转换到错误的类(接口(interface))

标签 java kotlin twitter4j

最近我一直在研究 Kotlin,它非常棒!

我正在使用 Twitter4j 库来尝试使用 Twitter API 进行一些操作。我用 Kotlin 写了这段代码

object Demo {

    private val twitterStream = TwitterStreamFactory().instance
    @JvmStatic
    fun main(args: Array<String>) {

        val listener = object : StatusListener {

            override fun onStallWarning(warning: StallWarning?) {
                println("Got stall warning:" + warning)
            }

            override fun onScrubGeo(userId: Long, upToStatusId: Long) {
                println("Got scrub_geo event userId:$userId upToStatusId:$upToStatusId")
            }

            override fun onStatus(status: Status) {
                println("@" + status.user.screenName + " - " + status.text)
            }

            override fun onDeletionNotice(statusDeletionNotice: StatusDeletionNotice) {
                println("Got a status deletion notice id:" + statusDeletionNotice.statusId)
            }
            override fun onTrackLimitationNotice(numberOfLimitedStatuses: Int) {
                println("Got track limitation notice:" + numberOfLimitedStatuses)
            }
            override fun onException(ex: Exception) {
                ex.printStackTrace()
            }
        }

        twitterStream.addListener(listener)
        twitterStream.sample()

    }
}

但每次运行它时,我都在线程“main”java.lang.IllegalAccessError 中得到了异常:试图从类 co.enoobong.eno.twitter.bot.Demo 访问类 twitter4j.StreamListener 在 co.enoobong.eno.twitter.bot.Demo.main(Demo.kt:63)

进一步调查后,工具->Kotlin->显示 Kotlin 字节码。我反编译成 Java,才发现生成的是这个。

 @JvmStatic
 public static final void main(@NotNull String[] args) {
  Intrinsics.checkParameterIsNotNull(args, "args");
  <undefinedtype> listener = new StatusListener() {
     public void onStallWarning(@Nullable StallWarning warning) {
        String var2 = "Got stall warning:" + warning;
        System.out.println(var2);
     }

     public void onScrubGeo(long userId, long upToStatusId) {
        String var5 = "Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId;
        System.out.println(var5);
     }

     public void onStatus(@NotNull Status status) {
        Intrinsics.checkParameterIsNotNull(status, "status");
        String var2 = "@" + status.getUser().getScreenName() + " - " + status.getText();
        System.out.println(var2);
     }

     public void onDeletionNotice(@NotNull StatusDeletionNotice statusDeletionNotice) {
        Intrinsics.checkParameterIsNotNull(statusDeletionNotice, "statusDeletionNotice");
        String var2 = "Got a status deletion notice id:" + statusDeletionNotice.getStatusId();
        System.out.println(var2);
     }

     public void onTrackLimitationNotice(int numberOfLimitedStatuses) {
        String var2 = "Got track limitation notice:" + numberOfLimitedStatuses;
        System.out.println(var2);
     }

     public void onException(@NotNull Exception ex) {
        Intrinsics.checkParameterIsNotNull(ex, "ex");
        ex.printStackTrace();
     }
  };
  twitterStream.addListener((StreamListener)listener);
  twitterStream.sample();

Kotlin 试图将监听器转换为库中私有(private)的 StreamListener(StatusListener 扩展它)因此 IllegalAccessError

有什么解决办法吗?

PS:这是代码的工作 Java 版本 - https://github.com/yusuke/twitter4j/blob/master/twitter4j-examples/src/main/java/twitter4j/examples/stream/PrintSampleStream.java

PPS:我在 IntelliJ IDEA 2017.2.2 上使用 Kotlin 1.1.4

最佳答案

Kotlin 添加这些转换以确保在处理重载方法时调用正确的方法。出现此问题是因为公共(public) API addListener 需要包私有(private)接口(interface) StreamListener。尝试创建这样的 api 实际上会因为这个问题而导致警告,应该在 Twitter4j 方面修复。

在 Kotlin 中没有直接的方法来解决这个问题,您可以使用 Java 帮助类和扩展方法来解决这个问题:

class Twitter4jFixer {
    public static void addListener(TwitterStream stream, StatusListener listener) {
        stream.addListener(listener);
    }
}


fun TwitterStream.addListenerFixed(listener: StatusListener) {
    Twitter4jFixer.addListener(this, listener)
}

关于java - 如何让 Kotlin 停止将参数转换到错误的类(接口(interface)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45781964/

相关文章:

java - 如何在 Eclipse 中打开 Java、Scala 和 JRuby 的单个项目?

intellij-idea - 无法运行 kotline 临时文件

kotlin - 如何将 vararg 作为数组传递给 Kotlin 中的函数?

java - Heroku "Cannot run more than 1 Free size dynos"但我只想运行一个

java - 在哪里可以从 Twitter 搜索返回的 HttpClient 获取 http 响应代码?

java - 如何判断字符串中是否存在未知数字?

Java 客户端-服务器聊天应用程序获取 java.net.SocketException : Socket closed

java - SocketChannel.write() 在单个线程中处理多个客户端

android - Kotlin `apply()` Dart 中的方法模拟

java - 如何在不暴露我的 oauth secret token 的情况下在开源中使用 Twitter4J?