2017-09-19 9 views
7

私はKotlinを学習しています。それ以前は、Android開発用のJavaで作業しました。コトリンは学ぶのに最適な言語です。私はsetOnClickListener(View.OnClickListener)を使っている間に混乱しています。私はAndroid Studioで2つのヒントを見てきました。KotlinのOnclickListenerメソッドの違い

image

私はそれらの両方を仕事や定義する方法を知っています。

OnClickListerner

send_button.setOnClickListener(object : View.OnClickListener{ 
     override fun onClick(p0: View?) { 
      TODO("not implemented") //To change body of created functions use File | Settings | File Templates. 
     } 
    }) 

を実装する最初の方法は、これが第二の方法は、ラムダに基づいているように、私は限り理解OnClickListener

send_button.setOnClickListener { 
     TODO("not implemented") //To change body of created functions use File | Settings | File Templates. 
    } 

を実装する第2の方法です。しかし、私はこれらの方法を正しく理解することはできません。

私の質問は次のとおりです。これらの方法の違いは何ですか?それらが異なる場合は、どちらがより優れていて、なぜですか?

答えて

2

彼らは同じ関数を参照するが、異なる方法で書かれている願っています。最初のものは、OnClickListenerオブジェクトを受け入れるsetOnClickListener()関数を呼び出す一般的な方法です。

第2のものはラムダ式を使用する。これは、View.OnClickListenerがJavaで定義されたSAM typeであり、KotlinがSAM conversionsをサポートしているために機能します。

Java 8と同様、KotlinはSAM変換をサポートしています。これは、Kotlin関数リテラルが、インタフェースメソッドのパラメータ型がKotlin関数のパラメータ型と一致する限り、デフォルト以外の単一のメソッドでJavaインタフェースの実装に自動的に変換できることを意味します。

あなたはこのようにJavaで定義されたインタフェースを持っていると仮定します。

public class Example { 
    public interface SingleMethodInterface { 
     int length(String text); 
    } 

    public static void set(SingleMethodInterface sam) {} 
} 

その後、あなたはKotlinで、次の二つの方法でset()関数を呼び出すことができます。SAM、要するに

//Passing a function type which accept a `String` and return an `Int` 
val length: (String) -> Int = { it.length } 
Example.set(length) 
//or 
Example.set { it.length } 

//Passing an object which implements `SingleMethodInterface` 
val length2: Main.SingleMethodInterface = object: Main.SingleMethodInterface { 
    override fun length(text: String): Int { 
     return text.length 
    } 
} 
Example.set(length2) 

変換は、Javaと相互に作用するKotlinでクリーンなコードを書く方法を提供します。

+0

ニースの情報人ですが、あなたの例は彼の質問には関係ありません。 –

+0

@Bhuvanesh Bs私が追加した例は、SAM変換を説明するために使用されています。 – BakaWaii

+1

この素晴らしい情報を共有してくれてありがとう@BakaWaii。 – UltimateDevil

3

あなたの質問: これらの方法の違いは何ですか?それらが異なる場合は、どちらがより優れていて、なぜですか?

コンパイル後、両方とも同じバイトコードが生成されますが、書き込み中は1行の読み込みで読みやすくなります。

Java 8の大きな特長は、ラムダ式です。ラムダを使うと、より簡単なJavaコードを書くことができます。コードの醜い外観は、この機能によってわずかに変更されました。

例:source

あなたはラムダとしてシングル抽象メソッド(SAM)を書くことができます。

インターフェイスには1つの方法しかない場合。

public interface StateChangeListener { 

    public void onStateChange(State oldState, State newState); 

} 

このようにラムダとして書くことができます。

stateOwner.addStateListener(
    (oldState, newState) -> System.out.println("State changed") 
); 

しかし、どちらの方法も同じですが、2番目の方法はとても単純で醜い実装であることがわかります。

Kotlinでは、ラムダ式はJavaと異なります。

Kotlinラムダ表現の例:source

val add: (Int, Int) -> Int = { a, b -> a + b } 

上記の関数の変数は次のように呼び出すことができます。

val addedValue: Int = add(5, 5) 

これはあなたに二つの整数の付加価値を返します。

この例では、(Int, Int) -> Intが表示されています。これはKotlinのラムダ関数と呼ばれています。

だから、Kotlinラムダ関数とJavaラムダ関数は全く異なっています。あなたはKotlinドキュメントで見ることができます

だけのJava 8のように、Kotlinは、SAMの変換をサポートしています。これは、 Kotlin関数リテラルが、 インタフェースのパラメータタイプが のKotlin関数のパラメータタイプと一致する限り、 という単一のデフォルト以外のメソッドを持つJavaインターフェイスの実装に自動的に変換できることを意味します。

実際には、kotlinでラムダを書いており、後でそれがjavaインターフェイスに変換されます。したがって、両方の方法が異なります。しかし、それが実行になると、どちらも同じです。コンパイル時間には影響しないので、ラムダを使用することが常に推奨されます。

は、それが役立ちます:)

+0

彼はラムダ法とノーマル法の違いを尋ねました。 @Intellij Amiya –

+1

@IntelliJAmiyaにお返事ありがとうございます。それは私に多くの理解を助ける。 setOnClickListener transformation – UltimateDevil

関連する問題