2017-08-20 3 views
5

最近のKotlinで回ってきた、それは素晴らしいです!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() 

    } 
} 

にこのコードを書いたが、私はそれを実行したたびに、私はさらに調査、ツール - > Kotlin->ショーKotlinバイトコードの際に

exception in thread "main" java.lang.IllegalAccessError: tried to access class twitter4j.StreamListener from class co.enoobong.eno.twitter.bot.Demo at co.enoobong.eno.twitter.bot.Demo.main(Demo.kt:63)を得ました。私はJavaに逆コンパイルして、これが生成されていることを発見するだけです。 (StatusListenerはそれを拡張する)ので、IllegalAccessError

任意のアイデアはどのようにしてください解決するためのライブラリでプライベートでKotlinはStreamListenerにリスナーをキャストしようとしていた

@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(); 

}?

PS:ここでは、コードの作業Java版だ - https://github.com/yusuke/twitter4j/blob/master/twitter4j-examples/src/main/java/twitter4j/examples/stream/PrintSampleStream.java

PPS:私はのIntelliJ IDEAに、Kotlin 1.1.4を使用していKotlinは正しい方法を確認するためにこれらのキャストを追加2017年2月2日

答えて

2

オーバーロードされたメソッドを処理するときに呼び出されます。この問題は、パブリックAPI addListenerがパッケージプライベートインターフェイス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) 
} 
+0

ご回答ありがとうございます@Kiskae。私はこれを試してみよう。実際にはJavaで完璧に動作するので、修正プログラムの必要はありません – Enoobong

+0

あまりにも魅力的なように働いた。多くのありがとう – Enoobong

0

Kiskaeはtwitter4jの著者はないかもしれない、良い点を置きます他のjvm言語とのやりとりを考慮しないでください。

私は修正が必要だとは思わない。

不要なキャストのために、パッケージプライベートインターフェイスtwitter4j.StreamListenerを使用する必要がある場合は、クラスをpackage twitter4jに入れることができます。

+0

あなたのお返事ありがとうございます@aristottl!クラスを 'package twitter4j'に入れるにはどうすればいいですか?それは外部ライブラリです。依存関係をpom.xmlに追加しました – Enoobong

+0

@Enoobong名前は 'twitter4j'という名前の新しいパッケージを作成するだけです。 – aristotll

+0

細かい魅力のように働いた。どうもありがとう! – Enoobong

関連する問題