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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 00:50:15  来源:igfitidea点击:

What is the equivalent of the C# 'var' keyword in Java?

javakeywordvar

提问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 varkeyword 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.

  • varis not the same as dynamic. variables are still 100% statically typed. This will not compile:

    var myString = "foo";
    myString = 3;
    
  • varis 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, currentUserhas a Useror derived class in it. Obviously, if your implementation of User.GetCurrentreturn 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 (eg new 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 varwithout 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不一样dynamicvariables 仍然是 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关键字。

http://projectlombok.org/features/val.html

http://projectlombok.org/features/val.html

回答by balpha

I have cooked up a plugin for IntelliJ that – in a way – gives you varin 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

You can take a look to Kotlinby JetBrains, but it's val. not var.

你可以看看JetBrains 的Kotlin,但它是 val。不是变种

回答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

Lomboksupports 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 valis support by Lombokas 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:

笔记:

  • varis 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 varwhich 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 varand anonymous classes (that you should never use at work).

它还可以推断不可表示的类型(程序员无法在该位置命名的类型;尽管哪些类型是不可表示的是不同的)。参见例如Tricks withvar和匿名类(你永远不应该在工作中使用)

The one difference I could find is that in C#,

我能找到的一个区别是在 C# 中,

If a type named var is in scope, then the var keyword will resolve to that type name and will not be treated as part of an implicitly typed local variable declaration.

如果名为 var 的类型在范围内,则 var 关键字将解析为该类型名称,并且不会被视为隐式类型局部变量声明的一部分。

In Java 10 varis not a legal type name.

在 Java 10var中不是合法的类型名称。