2015-12-25 10 views
7

私は、静的に型指定されているプログラミング言語の利点を理解しようとしています。それを通して、なぜ型を宣言に含める必要があるのでしょうか?タイプを明示的にするのではなく、目的に合っていますか?この場合、私はその点を見ません。私は静的な型指定はコンパイル時に型チェックを可能にすることを理解していますが、明示的な型宣言を省略すると、Javaはコンパイル時に型を推測できませんか?静的型付き言語で型の宣言が重要なのはなぜですか?

例えば、我々はJavaで持っているとしましょう:

myClass test = new myClass(); 

は、ここでは、不要な型宣言はありませんか?私が間違っていない場合、これは静的バインディングであり、JavaはtestがタイプmyClassであることを知っておく必要があります。コンパイル時でも型の明示的な宣言はありません。

重複する可能性への応答:これは、静的型と動的型に関する質問ではなく、受け入れられた回答で説明されている静的型付き言語の型推論に関するものです。

+3

'クラスBは拡張A '、' AはA =新しいB() 'でしょうか?コンパイラは 'a'の型をどのように推測すべきですか? – gefei

+0

@femtoRgonこの質問は、静的型付き言語の型推論、動的型付き言語の型推論に関するものです。 – yshavit

+0

申し訳ありませんが、*動的に型付けされた言語に関するものではありません。 :) – yshavit

答えて

11

ここでは、型宣言を省略できるようにするために、静的型付き言語であるです。これはtype inferenceと呼ばれます。欠点は、(言語設計者のために)設計するのが難しく、(コンパイラ作家のために)実装するのが難しく、何かがうまくいかないとき(プログラマにとって)理解するのが難しいことです。最後の問題は、多くの(またはすべての)型が推測された場合、コンパイラは「型がすべて一貫しているわけではない」よりもはるかに多くを伝えることができないということです。

あなたが引用したような単純なケースでは、はい、簡単です。しかし、あなたが些細なケースから遠ざかるにつれ、システムは急速に複雑になります。

Javaは、実際には非常に限定された形で型推論を行います。例えば、このスニペットで:

List<String> emptyStrings = Collections.emptyList(); 

...コンパイラは、メソッド呼び出しemptyListがタイプTが指定されていないだけでList<T>List<String>を返し、ないものと推察しています。その行の非推論バージョン(有効なJavaも)は次のとおりです。

List<String> emptyStrings = Collections.<String> emptyList(); 
+1

これはまさに私が不思議に思っていたものです。ありがとうございます!だから私は別の同様の質問があります:宣言された型は、Javaのような言語で異なる量のメモリを割り当てますか? 'A ';' 'B';' 'と同じように、' A'に100個のインスタンス変数があり、Bに0がある場合、宣言時に何か違いがあるのか​​、インスタンス化時に来るのでしょうか?プリミティブはどうですか? – rb612

+2

@ rb612全く違いはありません。メモリは、それを参照するのではなく、オブジェクトによって純粋に決定されます。参照は単なる固定サイズなので、 'String a'、' List b'、 'ArrayList > c 'の3つの参照はすべて同じスペースを使います(実際はJVMが勝ったそれらが「あるオブジェクトへの参照」以外の何かであることも知っている)。プリミティブには多相性はありませんが、サイズは異なります(バイトは1バイト、ショートは2バイトなど)。 – yshavit

+0

それは素晴らしいです、ありがとう!本質的には、Javaのような静的型付き言語での型の明示的宣言は、型推論を避けるためだけに役立ち、メモリ割り当てとは何の関係もありません。 – rb612

1

必要です。型が必要な継承を持つことができます。例えば

Building build1 = new House(); 
Building build2 = new SkyScraper(); 

これは多型で同じです。

たとえば、Buildingをすべて配列に集めることができます。 HouseSkyScraperの1つがある場合、これを行うことはできません。

+0

右、私はそれを見ることができます。しかし、build1を 'house1 = new House();'のようにhouse1にしたい場合は、最初のHouseを削除して 'build1 = new House();'を書くべきではないでしょうか? – rb612

+0

回答済み@ rb612 – maskacovnik

+0

ありがとうございます。私の質問は正しいとは言えず、タイプ推論と関連があります。これは@yshavitの答えで説明されています。 – rb612

関連する問題