2013-10-13 15 views
9

私はこのようになりますJavaのクラスを持っている:ScalaはJavaの内部クラスにアクセスできません。

public class Constants { 
    public class Commands { 
     public static final String CreateOrder = "CreateOrder"; 
    } 
} 

私はJavaで私はこのように簡単にアクセスすることができ、一定の「CreateOrder」にアクセスしたい:

String co = Constants.Commands.CreateOrder 

しかし、Scalaで、このdoesnのなぜうまくいかない? Scalaから "CreateOrder"にアクセスするには、Javaコードを変更できません。

ありがとうございました。

+0

'Constants $ Command $ CreateOrder'を試すことができますか? –

+0

定数$ Command $ CreateOrderは機能しませんでした – Mustafa

+1

なぜ 'Commands'は非静的ですか? –

答えて

5

私が知る限り、あなたが望むことをScalaで行う方法はありません。

しかし、あなたが絶対にJavaコードを変更できない場合は、いくつかの反射のトリッキーに頼ることができます。

val value = classOf[Constants#Commands].getDeclaredField("CreateOrder").get(null) 
+0

この問題を解決するために何時間も費やしました。私はこのように定義された定数を持つサードパーティのlibを使用しています。これが働いたのはこれだけでした。 @Travis Brownがオブジェクトをインスタンス化してアクセスするという提案は、私にとってはうまくいかなかった。 –

4

Java Language Specificationから:彼らは一定の変数(§4.12.4)でない限り、

内部クラスは、静的メンバを宣言しないことがあり、コンパイル時エラーが発生します。通常Constants.Commandsへの参照がConstantsのインスタンスに関連付けられなければならないにもかかわらず、それは静的な内部クラスではありませんので、

は、一定の変数の場合は、あなたは、 Constants.Commands.CreateOrder構文を使用することができます。

これは、Javaの奇妙な一意の構文上の特殊ケースの1つと考えることができますが、Scalaの言語設計者がScalaのJava相互運用性に慣れさせていないようなものです。

あなたは完全に自然な方法で内部クラスの静的フィールドにアクセスすることができ、その時点で最善の策(あなたの本当のJavaクラスは、まさにこのように見える場合)Constantsのインスタンスを作成することです、:

scala> (new Constants).Commands.CreateOrder 
res0: String = CreateOrder 

何らかの理由でこれがオプションではない場合は、残念なことに、他の回答でリフレクションベースのアプローチを行う必要があります。

3

私はリフレクションとインスタンス化の第3の選択肢は、Javaグルーコードの小さな断片を書くことだと思います。同様に

public class Glue { 
    public static String createOrder() { return Constants.Commands.CreateOrder; } 
} 

次に、Glue.createOrderと書くことができます。

+0

これは私の反射ベースの答えの良い代替手段です。新しいJavaコードをアプリケーションに追加することができる/許可されている場合、これは優れたオプションです。 – monkjack

+1

サイドノートとして:sbtを使ってビルドするときに、.javaファイルをミックスに投げ込むことは、すぐに行えます。 JavaとScalaの見解が一致しないコーナーケースをすばやく解決することがよくあります(私は可視性が別のケースだと思います) –

関連する問題