2016-08-10 10 views
6

Swiftでは、既存のクラスの拡張を作成して、必要に応じて既存のクラスに関数を追加することができます。これは、既存のクラスのサブクラスを作成しないようにするのにも役立ちます。JavaはSwiftのようなクラス拡張をサポートしていますか?

同様の機能がJavaに存在するかどうか疑問に思っていましたか?既存のJavaクラスにメソッドを追加する唯一の方法は、既存のクラスのサブクラスを作成することですか?

+2

Javaにはありません。しかし、誰もがScalaで言うことに満足しているわけではありません。読みやすさ、保守性を妨げる可能性があるため。通常、XxxUtilsやXxxsなどの関数を持つクラスを作成します。継承には独自の問題があります(最終的なクラス、古いコードの強制的な不完全さ、集中管理=ただ1つの拡張ポイント)。 –

答えて

5

いいえ、バニラJavaには拡張メソッドはありません。しかし、Lombokは、そのアノテーションとバイトコードの生成のおかげで、拡張メソッド構文を含む多くの便利な機能を追加しています。

注釈の@ExtensionMethod注釈を使用して、既存の静的メソッドを拡張メソッドに「変換する」ことができます。静的メソッドの最初のパラメータは基本的にthisになります。 - 限り静的メソッドがnull-安全であるとして、NullPointerExceptionがスローされることはありませんロンボク拡張メソッドがnullのオブジェクトに「呼び出された」ことができることを

import lombok.experimental.ExtensionMethod; 

@ExtensionMethod({java.util.Arrays.class, Extensions.class}) 
public class ExtensionMethodExample { 
    public String test() { 
    int[] intArray = {5, 3, 8, 2}; 
    intArray.sort(); 

    String iAmNull = null; 
    return iAmNull.or("hELlO, WORlD!".toTitleCase()); 
    } 
} 

class Extensions { 
    public static <T> T or(T obj, T ifNull) { 
    return obj != null ? obj : ifNull; 
    } 

    public static String toTitleCase(String in) { 
    if (in.isEmpty()) return in; 
    return "" + Character.toTitleCase(in.charAt(0)) + 
     in.substring(1).toLowerCase(); 
    } 
} 

注:たとえば、これは有効なロンボク強化Javaコードでありますこれは基本的に静的メソッド呼び出しに変換されるためです。はい、それは構文の砂糖になりますが、これは通常の静的メソッド呼び出しよりも読みやすいと思います。

他にも、Javaの相互運用性を備えた他のJVM言語をプロジェクトで使用できます。たとえば、Kotlinには、extension methods functionalityが付属しています。また、標準ライブラリですでに定義されている便利な拡張機能もあります。ここにはKotlin and Lombok comparisonがあります。

1

Decorator Patternはおそらく最も近いものです。既存のクラスの機能を強化するために、型の互換性と構成を維持するためにインタフェースを使用します。あなたが説明しているものと同じ原理ではありませんが、同じ目的を果たすかもしれません。

2

これは、Scala、Groovy、またはClosureのようなJVMの他の言語でも実行できます。 Groovyで例えば

あなたが implicit conversionsを使用することができScalaで
List.metaClass.printSize = { 
    println delegate.size() 
} 

[1,2,3].printSize() //prints 3 

class PrefixedString(val s: String) { 
    def prefix = "prefix_" + s 
} 

implicit def stringToString(s: String) = new PrefixedString(s) 

"foo".prefix // returns "prefix_foo" 

this article.

重要発言の表情は、Groovyの/ Scalaのソースコードがあるということである持っていてください結果として得られるクラスをJavaコードで使用できるように、Javaバイトコードにコンパイルされることを意図しています。

+1

さらに、ロンボクは内部的にいくつかの魔法をしますが、それは "不可能"という言葉がまったく真実ではないと言っています。 – JustACluelessNewbie

+1

ok、ありがとう、私はちょうど私のawserを更新しました。 –

+0

Scalaの例では、 'extends AnyVal'を使用する'暗黙のクラス ' – Clashsoft

関連する問題