Java 中 C# 'var' 关键字的等价物是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3443858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the equivalent of the C# 'var' keyword in Java?
提问by Arturo
One use of the varkeyword in C# is implicit type declaration. What is the Java equivalent syntax for var?
C# 中var关键字的一种用法是隐式类型声明。var的 Java 等效语法是什么?
采纳答案by Mike Caron
There is none. Alas, you have to type out the full type name.
空无一人。唉,你必须输入完整的类型名称。
Edit: 7 years after being posted, type inference for local variables (with var
) was added in Java 10.
编辑:发布 7 年后,var
在 Java 10 中添加了局部变量(with )的类型推断。
Edit: 6 years after being posted, to collect some of the comments from below:
编辑:发布6年后,从下面收集一些评论:
The reason C# has the
var
keyword is because it's possible to have Types that have no name in .NET. Eg:var myData = new { a = 1, b = "2" };
In this case, it would be impossible to give a proper type to
myData
. 6 years ago, this was impossible in Java (all Types had names, even if they were extremely verbose and unweildy). I do not know if this has changed in the mean time.var
is not the same asdynamic
.var
iables are still 100% statically typed. This will not compile:var myString = "foo"; myString = 3;
var
is also useful when the type is obvious from context. For example:var currentUser = User.GetCurrent();
I can say that in any code that I am responsible for,
currentUser
has aUser
or derived class in it. Obviously, if your implementation ofUser.GetCurrent
return an int, then maybe this is a detriment to you.This has nothing to do with
var
, but if you have weird inheritance hierarchies where you shadow methods with other methods (egnew public void DoAThing()
), don't forget that non-virtual methods are affected by the Type they are cast as.I can't imagine a real world scenario where this is indicative of good design, but this may not work as you expect:
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
As indicated, virtual methods are not affected by this.
No, there is no non-clumsy way to initialize a
var
without an actual variable.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
In this case, just do it the old fashioned way:
object foo6;
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()
)隐藏方法,请不要忘记非虚拟方法会受到它们被强制转换为的类型的影响。我无法想象一个现实世界的场景,这表明设计良好,但这可能不像你期望的那样工作:
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
没有实际变量的 a 。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;
回答by darthtrevino
If you add Lombok to your project you can use its valkeyword.
如果您将 Lombok 添加到您的项目中,您可以使用其val关键字。
回答by balpha
I have cooked up a plugin for IntelliJ that – in a way – gives you var
in Java. It's a hack, so the usual disclaimers apply, but if you use IntelliJ for your Java development and want to try it out, it's at https://bitbucket.org/balpha/varsity.
我为 IntelliJ 编写了一个插件,在某种程度上,它为您提供var
了 Java。这是一个 hack,所以通常的免责声明适用,但如果您使用 IntelliJ 进行 Java 开发并想尝试一下,它在https://bitbucket.org/balpha/varsity。
回答by JonnyRaa
A simple solution (assuming you're using a decent IDE) is to just type 'int' everywhere and then get it to set the type for you.
一个简单的解决方案(假设您使用的是不错的 IDE)是在任何地方输入“int”,然后让它为您设置类型。
I actually just added a class called 'var' so I don't have to type something different.
我实际上只是添加了一个名为“var”的类,因此我不必键入不同的内容。
The code is still too verbose, but at least you don't have to type it!
代码还是太冗长了,但至少不用打字了!
回答by Sebastian Zaba
I know this is older but why not create a var class and create constructors with different types and depending on what constructors gets invoked you get var with different type. You could even build in methods to convert one type to another.
我知道这是旧的,但为什么不创建一个 var 类并创建具有不同类型的构造函数,并且根据调用的构造函数,您会得到不同类型的 var。您甚至可以内置方法将一种类型转换为另一种类型。
回答by Artiom
回答by blueberry0xff
JEP - JDK Enhancement-Proposal
JEP - JDK 增强建议
http://openjdk.java.net/jeps/286
http://openjdk.java.net/jeps/286
JEP 286: Local-Variable Type Inference
JEP 286:局部变量类型推断
Author Brian Goetz
作者布赖恩·戈茨
// Goals:
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
回答by BullyWiiPlaza
Lombok
supports varbut it's still classified as experimental:
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);
Hereis a pitfall to avoid when trying to use it in IntelliJ IDEA
. It appears to work as expected though including auto completion and everything. Until there is a "non-hacky" solution (e.g. due to JEP 286: Local-Variable Type Inference), this might be your best bet right now.
这是尝试在IntelliJ IDEA
. 虽然包括自动完成和所有内容,但它似乎按预期工作。直到有一个“非hacky”的解决方案(例如,由于JEP 286: Local-Variable Type Inference),这可能是你现在最好的选择。
Note that val
is support by Lombok
as well without modifying or creating a lombok.config
.
请注意,val
是支持Lombok
,以及无需修改或创建lombok.config
。
回答by Maroun
It will be supported in JDK 10. It's even possible to see it in action in the early access build.
它将在 JDK 10 中得到支持。甚至可以在早期访问版本中看到它的运行情况。
The JEP 286:
该JEP 286:
Enhance the Java Language to extend type inference to declarations of local variables with initializers.
增强 Java 语言以将类型推断扩展到带有初始值设定项的局部变量声明。
So now instead of writing:
所以现在而不是写:
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
You write:
你写:
var list = new ArrayList<String>();
var stream = myStream();
Notes:
笔记:
var
is now a reserved type name- Java is stillcommitment to static typing!
- It can be only used in localvariable declarations
var
现在是保留类型名称- Java仍然致力于静态类型!
- 它只能用于局部变量声明
If you want to give it a try without installing Java on your local system, I created a Docker imagewith JDK 10 installed on it:
如果您想尝试一下而不在本地系统上安装 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 run
INFO: Created user preferences directory.
| Welcome to JShell -- Version 10
| For an introduction type: /help intro
jshell> var list = new ArrayList<String>();
list ==> []
回答by Alexey Romanov
Java 10 did get local variable type inference, so now it has var
which is pretty much equivalent to the C# one (so far as I am aware).
Java 10 确实获得了局部变量类型推断,所以现在它var
几乎等同于 C#(据我所知)。
It can also infer non-denotable types (types which couldn't be named in that place by the programmer; though whichtypes are non-denotable is different). See e.g. Tricks with var
and anonymous classes (that you should never use at work).
它还可以推断不可表示的类型(程序员无法在该位置命名的类型;尽管哪些类型是不可表示的是不同的)。参见例如Tricks withvar
和匿名类(你永远不应该在工作中使用)。
The one difference I could find is that in C#,
我能找到的一个区别是在 C# 中,
In Java 10 var
is not a legal type name.
在 Java 10var
中不是合法的类型名称。