C#でのvarキーワードの1つの使用法は、暗黙的な型宣言です。 varのJava同等の構文は何ですか?
なにもない。残念ながら、完全なタイプ名を入力する必要があります。
編集:投稿後7年で、ローカル変数の型推論(var
を使用)がJava 10に追加されました。
編集:投稿から6年後、以下からコメントの一部を収集します。
C#にvar
キーワードがあるのは、.NETで名前のないタイプを使用できるためです。例えば:
var myData = new { a = 1, b = "2" };
この場合、myData
に適切な型を与えることは不可能です。 6年前、これはJavaでは不可能でした(非常に冗長で扱いにくい場合でも、すべてのタイプに名前がありました)。この間に変更があったかどうかはわかりません。
var
はdynamic
と同じではありません。 var
iablesは、まだ100%静的に型付けされています。これはコンパイルされません:
var myString = "foo";
myString = 3;
var
は、型がコンテキストから明らかな場合にも役立ちます。例えば:
var currentUser = User.GetCurrent();
私が担当するどのコードでも、currentUser
にはUser
または派生クラスが含まれていると言えます。明らかに、User.GetCurrent
の実装がintを返す場合、これはあなたにとって有害かもしれません。
これはvar
とは関係ありませんが、他のメソッド(new public void DoAThing()
など)でメソッドをシャドウする奇妙な継承階層がある場合、非仮想メソッドはキャストされるTypeの影響を受けることを忘れないでください。
これが良いデザインを示す現実の世界のシナリオを想像することはできませんが、これはあなたが期待するように機能しないかもしれません:
class Foo {
public void Non() {}
public virtual void Virt() {}
}
class Bar : Foo {
public new void Non() {}
public override void Virt() {}
}
class Baz {
public static Foo GetFoo() {
return new Bar();
}
}
var foo = Baz.GetFoo();
foo.Non(); // <- Foo.Non, not Bar.Non
foo.Virt(); // <- Bar.Virt
var bar = (Bar)foo;
bar.Non(); // <- Bar.Non, not Foo.Non
bar.Virt(); // <- Still Bar.Virt
前述のように、仮想メソッドはこれによる影響を受けません。
いいえ、実際の変数なしでvar
を初期化する非面倒な方法はありません。
var foo1 = "bar"; //good
var foo2; //bad, what type?
var foo3 = null; //bad, null doesn't have a type
var foo4 = default(var); //what?
var foo5 = (object)null; //legal, but go home, you're drunk
この場合、昔ながらの方法で実行してください。
object foo6;
Lombokをプロジェクトに追加する場合、そのvalキーワードを使用できます。
JEP-JDK拡張-提案
http://openjdk.Java.net/jeps/286
JEP 286:ローカル変数型推論
著者ブライアンゲッツ
// Goals:
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
IntelliJ用のプラグインを作成しました。ある意味では、Javaでvar
を提供します。ハックなので、通常の免責事項が適用されますが、Java開発にIntelliJを使用して試してみたい場合は、 https://bitbucket.orgにあります。/balpha/varsity 。
3月20日にリリースされたJDK 10では、Javaに JEP 286 で指定されたvar
予約型名(キーワードではなく、以下を参照)が含まれるようになりました。ローカル変数の場合、次はJava 10以降で有効です。
var map = new HashMap<String, Integer>();
Javaのvar
予約型名は、C#のvar
キーワードとほぼ同じです。両方とも暗黙の型指定が可能です(重要な違いについては以下を参照)。 Javaのvar
は、次のコンテキスト( JEP 286:Goals に列挙されている)での暗黙的な型推論にのみ使用できます。
したがって、var
をフィールド、戻り値の型、クラス名、またはインターフェイス名に使用することはできません。その理由は、 JEP 286 (Brian Goetz著)で述べられているように、ローカル変数を宣言および定義するときに長い型名を含める必要をなくすことです。
開発者がローカル変数型の頻繁に不必要なマニフェスト宣言を排除できるようにすることで、静的型安全性に対するJavaのコミットメントを維持しながら、Javaコードの記述に関連する式を減らすことにより、開発者のエクスペリエンスを改善しようとしています.
var
Javaのスコープ
var
はJavaのキーワードではなく、予約された型名であることに注意してください。 JEP 286から引用したとおり:
識別子varはキーワードではありません。代わりに、予約されたタイプ名です。つまり、変数、メソッド、またはパッケージ名としてvarを使用するコードは影響を受けません。クラスまたはインターフェイス名としてvarを使用するコードは影響を受けます(ただし、これらの名前は通常の命名規則に違反するため、実際にはまれです)。
var
は予約された型名であり、キーワードではないため、パッケージ名、メソッド名、変数名(および新しい型干渉の役割)に使用できることに注意してください。たとえば、以下はJavaでのvar
の有効な使用例です。
var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;
JEP 286から引用したとおり:
この処理は、初期化子を持つローカル変数、拡張forループのインデックス、および従来のforループで宣言されたローカルに限定されます。メソッド形式、コンストラクタ形式、メソッド戻り型、フィールド、キャッチ形式、またはその他の種類の変数宣言には使用できません。
JavaとC#のvar
の違い
これは、C#のvar
とJavaの顕著な違いの1つです。以下を含みます。var
は、C#で型名として使用できますが、Javaでクラス名またはインターフェイス名として使用できません。 C#ドキュメント(暗黙的に型指定されたローカル変数) :
var
という名前の型がスコープ内にある場合、var
キーワードはその型名に解決され、暗黙的に型指定されたローカル変数宣言の一部として扱われません。
C#でvar
を型名として使用すると、複雑さが増し、複雑な解決規則が導入されます。これは、var
をクラス名またはインターフェイス名として禁止することで、Javaのvar
によって回避されます。 C#のvar
型名の複雑さについては、「 制限が暗黙的に型指定された変数宣言に適用される 」を参照してください。 Javaでの `varのスコープ決定の背後にある理論的根拠の詳細については、 JEP 286:Scoping Choices を参照してください。
JDK 10でサポートされる予定です。 early access build で動作を確認することもできます。
JEP 286 :
Java言語を拡張して、初期化子を使用してローカル変数の宣言に型推論を拡張します。
だから今書く代わりに:
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
あなたが書く:
var list = new ArrayList<String>();
var stream = myStream();
ノート:
var
は 予約済みの型名 になりましたローカルシステムにJavaをインストールせずに試してみたい場合、JDK 10がインストールされた Docker image を作成しました。
$ docker run -it marounbassam/ubuntu-Java10 bash
root@299d86f1c39a:/# jdk-10/bin/jshell
Mar 30, 2018 9:07:07 PM Java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
| Welcome to JShell -- Version 10
| For an introduction type: /help intro
jshell> var list = new ArrayList<String>();
list ==> []
簡単な解決策(まともなIDEを使用していると仮定)は、あらゆる場所に 'int'を入力し、タイプを設定するだけです。
実際に「var」というクラスを追加しただけなので、別のタイプを入力する必要はありません。
コードはまだ冗長すぎますが、少なくとも入力する必要はありません!
Java 10はローカル変数型の推論を取得したため、C#のものとほぼ同等のvar
を持っています(私が知っている限り)。
また、非表示型(プログラマがその場所に名前を付けることができなかった型。ただし、which型は非表示型とは異なります)たとえば、JavaにはC#の匿名型に相当するものはありません)。
私が見つけた1つの違いは、C#では、
varという名前の型がスコープ内にある場合、varキーワードはその型名に解決され、暗黙的に型指定されたローカル変数宣言の一部として扱われません。
Java 10では、var
は有効な型名ではありません。
JetBrainsによる Kotlin を見ることができますが、それはvalです。 varではありません.
私はこれが古いことを知っていますが、なぜvarクラスを作成し、異なるタイプのコンストラクタを作成して、呼び出されるコンストラクタに応じて異なるタイプのvarを取得してください。あるタイプを別のタイプに変換するメソッドを組み込むこともできます。
Java 10現在、同等のものは... var
です。
Lombok
はvarをサポートしています しかし、まだ実験的として分類されています:
import lombok.experimental.var;
var number = 1; // Inferred type: int
number = 2; // Legal reassign since var is not final
number = "Hi"; // Compilation error since a string cannot be assigned to an int variable
System.out.println(number);
ここ は、IntelliJ IDEA
で使用しようとするときに避けるべき落とし穴です。オートコンプリートなどすべてを含め、期待どおりに動作するようです。 「非ハッキング」ソリューション(たとえば、 JEP 286:Local-Variable Type Inference による)が見つかるまで、これが最善の策かもしれません。
val
は、lombok.config
を変更または作成せずに、Lombok
でもサポートされていることに注意してください。
Java 10では、Local変数に対してのみ、つまり、
あなたはできる、
var anum = 10; var aString = "Var";
しかし、できません、
var anull = null; // Since the type can't be inferred in this case
詳細については、 spec をご覧ください。
一般に、任意の型に対してObjectクラスを使用できますが、後で型キャストを行う必要があります!
例えば:-
Object object = 12;
Object object1 = "Aditya";
Object object2 = 12.12;
System.out.println(Integer.parseInt(object.toString()) + 2);
System.out.println(object1.toString() + " Kumar");
System.out.println(Double.parseDouble(object2.toString()) + 2.12);