最近我一直在研究 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/