回答:
ラチェットフリークの回答とコメントスレッドには、かなり誤った情報が含まれています。コメントが小さすぎるため、ここで回答します。また、これは結局答えなので、元の質問にも答えようとします。(ただし、私は型システムの専門家ではないことに注意してください。)
最初に、元の質問に対する短い答えは「はい」と「いいえ」です。はい、Java 8はJava 7よりもかなり多くの型推論を持ちます。いいえ、Java 8には「新しい」型システムはありません。
Java 8は依然として静的に型付けされ、クラスとインターフェースの間にはまだ二分されています。関数型などの新しい型はありません。ラムダのタイプは、基本的に単一の抽象メソッドを持つ通常のインターフェイスである「機能的インターフェイス」です。
インターフェイスは、デフォルトメソッドの形式でコードを持つことができますが、クラスの単一継承とインターフェイスの多重継承のモデルは同じままです。もちろん、デフォルトのメソッドが存在する場合のメソッド解決のルールなど、いくつかの調整がありますが、基本は変更されていません。
型の推論によって推論される型は、明示的に書き出すことができます。ラチェットフリークの例を使用するには、
Collections.<MyClass>sort(list, (a, b) -> { return a.order - b.order; });
基本的に砂糖です
Collections.<MyClass>sort(list,
(Comparator<MyClass>)((MyClass a, MyClass b) -> { return a.order - b.order; }));
したがって、sparkleshyの「型推論には型システムの拡張は必要ありません」という文は基本的に正しいです。
しかし、構文糖に戻るために、ラムダ式は匿名の内部クラスの構文糖ではないというステートメントを繰り返します。ラチェットフリークは、ラムダ式が匿名の内部クラスのインスタンス化に変換され、Sparkleshyがラムダが匿名の内部クラスの構文シュガーであることを再確認したが、これらのステートメントは間違っていると述べました。それらはおそらく古い情報に基づいています。初期のラムダ実装は、この方法でラムダを実装しましたが、状況は変わりました。
ラムダ式は、内部クラスと意味的に異なり、内部クラスとは異なる方法で実装されます。
ラムダ式は、いくつかの点で内部クラスと意味的に異なります。ラムダ式を評価するたびに新しいインスタンスを作成する必要はありません。また、キャプチャのセマンティクスも異なります。たとえば、これは異なる方法でキャプチャします。内部クラスでは、これは内部クラスのインスタンスですが、ラムダでは、これは包含インスタンスです。以下を考慮してください。
public class CaptureThis {
void a(Runnable r) { r.run(); }
void b() {
a(new Runnable() { public void run() { System.out.println(this); }});
a(() -> System.out.println(this));
}
public String toString() { return "outer"; }
public static void main(String[] args) { new CaptureThis().b(); }
}
最近のJDK 8 ラムダビルド(b69を使用しました)では、出力は次のようになります。
CaptureThis$1@113de03
outer
さらに、ラムダ式は、内部クラスとはまったく異なる方法で実装されます。逆アセンブルされた出力を比較すると、内部クラスコードが作成に直接コンパイルされ、CaptureThis $ 1のコンストラクターが呼び出されますが、ラムダ式はRunnableを取得するinvokedynamic命令にコンパイルされます。この仕組みと理由の詳細については、Brian GoetzのJavaOne 2012トークLambda:A Peek Under the Hoodをご覧ください。
this
とMyClass.this