在c#中var关键字的一种用法是隐式类型声明。Java中var的等效语法是什么?


当前回答

随着3月20日JDK 10的发布,Java现在包含了一个在JEP 286中指定的var保留类型名称(不是关键字,请参阅下文)。对于局部变量,以下语句现在在Java 10或更高版本中有效:

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

Java中的var保留类型名与c#中的var关键字几乎相同,因为两者都允许隐式类型(参见下面的重要区别)。var在Java中只能用于以下上下文中的隐式类型推断(如JEP 286: Goals中所列举的):

带有初始化式的局部变量 增强的for循环中的索引 在传统的for循环中声明了Locals

因此,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#和Java中var的一个显著区别,包括:var在c#中可以用作类型名,但在Java中不能用作类名或接口名。根据c#文档(隐式类型局部变量):

如果一个名为var的类型在作用域中,那么var关键字将解析为 该类型名不会被视为隐式类型的一部分 局部变量声明。

在c#中使用var作为类型名的能力带来了一些复杂性,并引入了一些复杂的解析规则,而在Java中,var通过禁止var作为类或接口名来避免这些问题。有关c#中var类型名称的复杂性的信息,请参见应用于隐式类型变量声明的限制。有关Java中' var的作用域决定背后的原理的更多信息,请参见JEP 286:作用域选择。

其他回答

在Java 10中可以,但只适用于局部变量,也就是说,

你可以,

是肛门 = 10;var aString = “Var”;

但是不能,

Var anull = null;//因为在这种情况下不能推断类型

查看规范以获得更多信息。

在Java 10中,等价的是……var。

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

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

编辑:在发布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 as dynamic. variables 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 a User or derived class in it. Obviously, if your implementation of User.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 (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 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;

JDK 10将支持它。甚至可以在早期访问版本中看到它的作用。

JEP 286:

增强Java语言,将类型推断扩展到带有初始化式的局部变量声明。

所以现在不要写:

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

你写的:

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

注:

Var现在是一个保留类型名 Java仍然致力于静态类型! 它只能在局部变量声明中使用


如果你想尝试一下,而不是在本地系统上安装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 ==> []

一般来说,你可以为任何类型使用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);