[英]What is the equivalent of the C# 'var' keyword in Java?
C# 中var關鍵字的一種用法是隱式類型聲明。 var的 Java 等效語法是什么?
空無一人。 唉,你必須輸入完整的類型名稱。
編輯:發布 7 年后,在 Java 10 中添加了局部變量(帶有var
)的類型推斷。
編輯:發布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()
) new public void DoAThing()
方法,請不要忘記非虛擬方法受它們new public void DoAThing()
為的類型的影響.
我無法想象一個現實世界的場景,這表明設計良好,但這可能不像你期望的那樣工作:
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
。 這是一個 hack,所以通常的免責聲明適用,但如果您使用 IntelliJ 進行 Java 開發並想嘗試一下,它位於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:目標中所列舉):
因此var
不能用於字段、返回類型、類名或接口名。 它的基本原理是在聲明和定義局部變量時不需要包含長類型名稱,如JEP 286 (由 Brian Goetz 撰寫)所述:
我們尋求通過減少與編寫 Java 代碼相關的儀式來改善開發人員體驗,同時通過允許開發人員省略通常不必要的局部變量類型的清單聲明,同時保持 Java 對靜態類型安全的承諾。
var
范圍需要注意的是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 循環中聲明的局部變量; 它不適用於方法形式、構造函數形式、方法返回類型、字段、捕獲形式或任何其他類型的變量聲明。
var
區別這是 C# 和 Java 中var
之間的一個顯着區別,包括: var
可以用作 C# 中的類型名稱,但不能用作 Java 中的類名稱或接口名稱。 根據C# 文檔(隱式類型局部變量) :
如果名為
var
的類型在范圍內,則var
關鍵字將解析為該類型名稱,並且不會被視為隱式類型局部變量聲明的一部分。
在使用的能力var
在C#中的類型名稱帶來了一些復雜性,並介紹了一些復雜的決策規則,這是由避免var
在Java中通過禁止var
作為一個類或接口的名稱。 有關 C# 中var
類型名稱復雜性的信息,請參閱適用於隱式類型變量聲明的限制。 有關 Java 中 `var 范圍決定背后的基本原理的更多信息,請參閱JEP 286:范圍選擇。
它將在 JDK 10 中得到支持。甚至可以在早期訪問版本中看到它的運行情況。
JEP 286 :
增強 Java 語言以將類型推斷擴展到帶有初始值設定項的局部變量聲明。
所以現在而不是寫:
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
你寫:
var list = new ArrayList<String>();
var stream = myStream();
筆記:
var
現在是保留類型名稱如果您想嘗試一下而不在本地系統上安裝 Java,我創建了一個安裝了 JDK 10 的Docker 鏡像:
$ 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 開始,等效項是 ... var
。
你可以看看 JetBrains 的Kotlin ,但它是 val。 不是變種
Java 10 確實獲得了局部變量類型推斷,所以現在它有var
,它幾乎等同於 C# 一個(據我所知)。
它還可以推斷不可表示的類型(程序員無法在該位置命名的類型;盡管哪些類型是不可表示的是不同的)。 參見例如使用var
和匿名類的技巧(你永遠不應該在工作中使用) 。
我能找到的一個區別是在 C# 中,
在 Java 10 中var
不是合法的類型名稱。
我知道這是舊的,但為什么不創建一個 var 類並創建具有不同類型的構造函數,並且根據調用的構造函數,您會得到不同類型的 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
使用它時要避免的一個陷阱。 雖然包括自動完成和所有內容,但它似乎按預期工作。 直到有一個“非hacky”的解決方案(例如,由於JEP 286: Local-Variable Type Inference ),這可能是你現在最好的選擇。
請注意, Lombok
也支持val
,而無需修改或創建lombok.config
。
你可以,在 Java 10 中,但僅限於局部變量,意思是,
你可以,
var anum = 10; var aString = "Var";
但不能,
var anull = null; // Since the type can't be inferred in this case
查看規范以獲取更多信息。
通常,您可以將 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);
這個特性現在在 Java SE 10 中可用。靜態的、類型安全的 var 終於進入了 Java 世界:)
來源: https : //www.oracle.com/corporate/pressrelease/Java-10-032018.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.