在Java中,C#的”var”关键字是什么等价物?

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

C中var关键字的一种用法是隐式类型声明。VaR的Java等价语法是什么?


没有。唉,您必须输入完整的类型名。

编辑:在发布7年后,在Java 10中添加了局部变量的类型推断(使用EDCOX1(0))。

编辑:发布6年后,收集以下评论:

  • C拥有var关键字的原因是因为.NET中可能有没有名称的类型。如:

    1
    var myData = new { a = 1, b ="2" };

    在这种情况下,不可能给myData一个合适的类型。6年前,在Java中这是不可能的(所有类型都有名字,即使它们非常冗长和不整洁)。我不知道这是否在同一时期发生了变化。

  • vardynamic不同。variables仍然是100%静态类型。这不会编译:

    1
    2
    var myString ="foo";
    myString = 3;
  • 当类型在上下文中很明显时,var也很有用。例如:

    1
    var currentUser = User.GetCurrent();

    我可以说,在我负责的任何代码中,currentUser中都有一个User或派生类。显然,如果您的User.GetCurrent的实现返回一个int,那么这可能对您不利。

  • 这与var无关,但是如果您有奇怪的继承层次结构,在这些层次结构中,您使用其他方法(例如new public void DoAThing()隐藏方法),请不要忘记非虚拟方法受其转换为的类型的影响。

    我无法想象一个现实世界中的场景,这意味着良好的设计,但这可能无法如您所期望的那样工作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    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

    1
    2
    3
    4
    5
    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

    在这种情况下,只需按传统方式操作:

    1
    object foo6;


如果你将lombok添加到你的项目中,你可以使用它的val关键字。

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


jep-jdk增强建议

http://openjdk.java.net/jeps/286

jep286:局部变量类型推断

作者布赖恩·戈茨

1
2
3
// Goals:
var list = new ArrayList<String>();  // infers ArrayList<String>
var stream = list.stream();          // infers Stream<String>


我已经为iTeliJi开发了一个插件,在某种程度上,它在Java中提供了EDCOX1×0。这是一个黑客,所以通常的免责声明适用,但如果你使用的是对你的Java开发的ITELLIJ,并尝试它,它是在HTTPS://ButButk.Org/BalpHa/ValeSt.


与"十通释的JDK(Java 3月20 var现在包括A型(不保留关键字的域名(看下面),为的是specified 286。局部变量,下面是现在有效期在Java 10或更高。

1
var map = new HashMap<String, Integer>();

var保留在Java的类型名identical冰近两个var关键字在C allow #在那两个隐式typlng(见下面的为重要的差异)。在只读varJava可以被用来隐式inference在下面的contexts(AS enumerated的目标是:在286):

  • 局部变量的初始化。
  • 属性的增强环路
  • locals宣布在一个传统的闭环

因此var不能被用来为田,返回的类型的名称、类或接口的名称。其理论基础是remove的需要包括长型的名称,当defining申报和局部变量,为286(除非是在城市authored Brian Goetz):

We seek to improve the developer experience by reducing the ceremony
associated with writing Java code, while maintaining Java's commitment
to static type safety, by allowing developers to elide the
often-unnecessary manifest declaration of local variable types.

在Java var范围

它应该是noted var冰槽,在Java关键字A,而A型,但保留名称。as quoted从286:是的

The identifier var is not a keyword; instead it is a reserved type
name. This means that code that uses var as a variable, method, or
package name will not be affected; code that uses var as a class or
interface name will be affected (but these names are rare in practice,
since they violate usual naming conventions).

注意,由于var类型名是一个保留关键字而不是一个静止的,它可以被用来作为包名、方法名和变量名(沿与它的新类型的干扰角色)。例如,下面的例子都有效(在Java var辨别:

1
2
3
4
5
var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;

as quoted从286:是的

This treatment would be restricted to local variables with
initializers, indexes in the enhanced for-loop, and locals declared in
a traditional for-loop; it would not be available for method formals,
constructor formals, method return types, fields, catch formals, or
any other kind of variable declaration.

之间的差异在Java var&;C #

这是一notable之间的差分varC和Java #包括以下:var可以被用来作为一种# name in C,但不能被用来作为一个类或接口的名称name in Java。根据《#文件(C型implicitly局部变量):

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.

使用的能力varAS name in C A型#创建一些复杂性和introduces intricate分辨率的一些规则,这是避免在城市var市disallowing var作为一类或接口的名称。信息在complexities名大学varC型的限制,适用于#,看到两个implicitly型变量的声明。更多信息在背后的理论基础的决策"的范围是在Java中,看到的是286:选择范围。


它将在JDK 10中得到支持。甚至可以在早期的访问构建中看到它的运行。

JEP 286:

Enhance the Java Language to extend type inference to declarations of local variables with initializers.

所以现在不用写了:

1
2
List<> list = new ArrayList<String>();
Stream<> stream = myStream();

你写:

1
2
var list = new ArrayList<String>();
var stream = myStream();

笔记:

  • var现在是保留的类型名
  • Java仍然致力于静态打字!
  • 它只能在局部变量声明中使用

如果您想尝试在本地系统上安装Java,我在JDK 10上安装了一个DOCKER映像:

1
2
3
4
5
6
7
8
9
$ 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 inference局部变量的类型,所以现在它具有var漂亮。这是两个等价的C #酮(SO的父亲为我意识到)。

它可以infer也非denotable类型(类型,不能被命名,在那地方的程序;但这类非denotable冰是不同的,例如Java有一个不等价的两个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.

在Java的10 var冰不是一个合法的类型名。


你可以通过JetBrains看看Kotlin,但它是Val,不是Var。


在Java中,10当量的冰淇淋……var


Lombok支持var,但仍属于实验类:

1
2
3
4
5
6
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:局部变量类型推断),否则这可能是您目前的最佳选择。

注意,val也由Lombok支持,不需要修改或创建lombok.config


我知道这是旧的,但为什么不创建一个var类,并创建具有不同类型的构造函数,根据调用的构造函数,您可以获得具有不同类型的var。甚至可以内置方法将一种类型转换为另一种类型。


你可以在Java中,10,但只读局部变量的意义,

你可以,

var anum = 10; var aString ="Var";

但不能,

var anull = null; // Since the type can't be inferred in this case

退房的规格的更多信息。


在总,你可以使用任何类型的对象的类,但是你有做型铸造以后!

如:

1
2
3
4
5
6
7
8
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看到10。在静态类型安全,终于有了做为《Java的世界:)

来源:http:/ / /公司/ www.oracle.com pressrelease / java-10-032018.html