拡張メソッドを使用してC#で行うように、オブジェクトのリストに機能を実装することを検討しています。
このようなもの:
List<DataObject> list;
// ... List initialization.
list.getData(id);
Javaでそれを行うにはどうすればよいですか?
Javaは拡張メソッドをサポートしていません。
代わりに、通常の静的メソッドを作成するか、独自のクラスを作成できます。
拡張メソッドは単なる静的メソッドではなく、単なる便利な構文シュガーではありません。実際、非常に強力なツールです。主なものは、異なるジェネリックのパラメーターのインスタンス化に基づいて異なるメソッドをオーバーライドする機能です。これはHaskellの型クラスに似ており、実際、C#のMonad(つまりLINQ)をサポートするためにC#にあるように見えます。 LINQ構文を削除しても、Javaで同様のインターフェイスを実装する方法はまだわかりません。
また、Javaのジェネリックパラメーターの型消去のセマンティクスのため、Javaでそれらを実装することは不可能だと思います。
Project Lombok は、注釈を提供します @ExtensionMethod
は、必要な機能を実現するために使用できます。
もう1つのオプションは、 ForwardingXXX google-guavaライブラリのクラスを使用することです。
Javaにはそのような機能はありません。代わりに、リスト実装の通常のサブクラスを作成するか、匿名の内部クラスを作成できます。
List<String> list = new ArrayList<String>() {
public String getData() {
return ""; // add your implementation here.
}
};
問題は、このメソッドを呼び出すことです。 「所定の場所で」実行できます。
new ArrayList<String>() {
public String getData() {
return ""; // add your implementation here.
}
}.getData();
技術的には、C#拡張にはJavaに相当するものはありません。しかし、よりクリーンなコードと保守性のためにそのような関数を実装したい場合は、Manifoldフレームワークを使用する必要があります。
package extensions.Java.lang.String;
import manifold.ext.api.*;
@Extension
public class MyStringExtension {
public static void print(@This String thiz) {
System.out.println(thiz);
}
@Extension
public static String lineSeparator() {
return System.lineSeparator();
}
}
マニホールド は、C#スタイルのJavaを提供します 拡張メソッド およびその他のいくつかの機能。他のツールとは異なり、マニフォールドには制限がなく、ジェネリック、ラムダ、IDEなどの問題から suffer がありません。マニフォールドは、F#スタイル カスタムtypes 、TypeScriptスタイル 構造インターフェース 、およびJavaScriptスタイル expandoタイプ 。
さらに、IntelliJはManifold plugin を介してManifoldの包括的なサポートを提供します。
Manifoldは、 github で利用可能なオープンソースプロジェクトです。
Defenderメソッド(つまり、デフォルトのメソッド)がJava 8になる可能性はわずかにありますが、私が理解している限り、author任意のユーザーではなく、interface
を遡及的に拡張します。
Defenderメソッド+インターフェイスインジェクションはC#スタイルの拡張メソッドを完全に実装できますが、AFAICS、インターフェイスインジェクションはまだJava 8ロードマップにはありません。
この質問でパーティーに少し遅れましたが、誰かがそれを便利だと思う場合に備えて、サブクラスを作成しました。
public class ArrayList2<T> extends ArrayList<T>
{
private static final long serialVersionUID = 1L;
public T getLast()
{
if (this.isEmpty())
{
return null;
}
else
{
return this.get(this.size() - 1);
}
}
}
装飾オブジェクト指向設計パターン を使用できます。 Javaの標準ライブラリで使用されているこのパターンの例は、 DataOutputStream です。
リストの機能を強化するためのコードを次に示します。
public class ListDecorator<E> implements List<E>
{
public final List<E> wrapee;
public ListDecorator(List<E> wrapee)
{
this.wrapee = wrapee;
}
// implementation of all the list's methods here...
public <R> ListDecorator<R> map(Transform<E,R> transformer)
{
ArrayList<R> result = new ArrayList<R>(size());
for (E element : this)
{
R transformed = transformer.transform(element);
result.add(transformed);
}
return new ListDecorator<R>(result);
}
}
PS私は Kotlin の大ファンです。拡張メソッドがあり、JVMでも実行されます。