2017-08-07 2 views
1

のstatic対:このJavaでGroovyの

protected static final Logger LOG = LoggerFactory.getLogger(this.getClass()) 

が、我々は静的コンテキストから非静的メンバにアクセスしようとしていることを意味する。このよう許可されていません。

しかし、Groovyでは同じコードを使用できます。どのように解決されるでしょうか?

は、それはこのように見えるようにコードを作る静的に優先権を与える:

protected static final Logger LOG = LoggerFactory.getLogger(MyClass.class) 

またはそれは非静的参照を優先となるだろうコードを見てのように:

protected final Logger LOG = LoggerFactory.getLogger(this.getClass()) 
+0

奇数これが動作するかどうか(私は今、バイトコードを調査する時間がありません)。レガシーロガーを使用している場合は '@ Slf4j'(または' @ Log4j')のASTは通常より単純です。 – chrylis

+1

それは、宣言と割り当てを分離することができます... –

答えて

3

Groovyのは、静的追加この初期化を満たすためのコンストラクタです。以下のクラスを見てみましょう:

groovyc -cp ~/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar ClassWithLog.groovy 

そして今のバイトコードがjavapコマンドを使用してどのようなものか見てみましょう:

javap -l -c ClassWithLog 

import org.slf4j.Logger 
import org.slf4j.LoggerFactory 

class ClassWithLog { 

    protected static final Logger LOG = LoggerFactory.getLogger(this.getClass()) 

    static void main(String[] args) { 
     LOG.info("Hello, world!") 
    } 
} 

はのは.classファイルにコンパイルしてみましょう

私は無関係のものをすべてスキップし、直接に行きます:(完全なリストはここにあります:https://gist.github.com/wololock/8d5a7cd049ef69a0d67567142e25b449

static {}; 
    Code: 
     0: invokestatic #23     // Method $getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite; 
     3: ldc   #89     // int 1 
     5: aaload 
     6: ldc   #91     // class org/slf4j/LoggerFactory 
     8: invokestatic #23     // Method $getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite; 
     11: ldc   #92     // int 2 
     13: aaload 
     14: ldc   #2     // class ClassWithLog 
     16: invokeinterface #96, 2   // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.callStatic:(Ljava/lang/Class;)Ljava/lang/Object; 
     21: invokeinterface #44, 3   // InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.call:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; 
     26: astore_0 
     27: aload_0 
     28: ldc   #98     // class org/slf4j/Logger 
     30: invokestatic #102    // Method org/codehaus/groovy/runtime/ScriptBytecodeAdapter.castToType:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object; 
     33: checkcast  #98     // class org/slf4j/Logger 
     36: putstatic  #36     // Field LOG:Lorg/slf4j/Logger; 
     39: aload_0 
     40: pop 
     41: return 
    LineNumberTable: 
     line 6: 0 

あなたが記載されたバイトコードに見ることができるように、Groovyは静的コンストラクタを追加しました(私たちはものを定義していない)と静的コンテキストで使用する場合には、this.getClass()の代わりにinvokestaticをしました。

この典型的なGroovyクラスから6行目を削除し、それをバイトコードにコンパイルすると、スタティックコンストラクタはもう存在しません。

静LOGフィールドを除去した後のフルバイトコードのリスト:https://gist.github.com/wololock/ad0284a0065166585dcba6a3db1475dc

関連する問題