Mik*_*ron 243
空无一人.唉,你必须输入完整的类型名称.
编辑:发布后7年,var在Java 10中添加了局部变量(with )的类型推断.
编辑:发布后6年,收集下面的一些评论:
C#具有var关键字的原因是因为可能在.NET中具有没有名称的类型.例如:
var myData = new { a = 1, b = "2" };
Run Code Online (Sandbox Code Playgroud)
在这种情况下,不可能给出合适的类型myData.6年前,这在Java中是不可能的(所有类型都有名字,即使它们非常冗长和不适合).我不知道这个时间是否有所改变.
var是不一样的dynamic.variables仍然是100%静态类型.这不会编译:
var myString = "foo";
myString = 3;
Run Code Online (Sandbox Code Playgroud)var当类型从上下文中显而易见时,它也很有用.例如:
var currentUser = User.GetCurrent();
Run Code Online (Sandbox Code Playgroud)
我可以说,在我负责的任何代码中,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
Run Code Online (Sandbox Code Playgroud)
如上所述,虚拟方法不受此影响.
不,在没有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
Run Code Online (Sandbox Code Playgroud)
在这种情况下,只需按照老式方式进行:
object foo6;
Run Code Online (Sandbox Code Playgroud)blu*_*xff 27
JEP - JDK增强 - 提案
http://openjdk.java.net/jeps/286
JEP 286:局部变量类型推断
作者Brian Goetz
// Goals:
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
Run Code Online (Sandbox Code Playgroud)
bal*_*pha 20
我已经为IntelliJ制作了一个插件 - 在某种程度上 - var用Java 提供给你.这是一个黑客,所以通常的免责声明适用,但如果您使用IntelliJ进行Java开发并想要尝试,请访问https://bitbucket.org/balpha/varsity.
Jus*_*ano 15
随着3月20日JDK 10的发布,Java现在包含了JEP 286中var指定的保留类型名称(不是关键字 - 见下文).对于局部变量,以下内容现在在Java 10或更高版本中有效:
var map = new HashMap<String, Integer>();
Run Code Online (Sandbox Code Playgroud)
varJava中的保留类型名称与varC#中的关键字几乎相同,因为它们都允许隐式类型(请参阅下面的重要差异).var在Java中,只能在以下上下文中用于隐式类型推断(如JEP 286:目标中所列举的):
因此var ,不能用于字段,返回类型,类名或接口名称.它的基本原理是去除需要包括长类型名称声明和定义局部变量的时候,在规定JEP 286 (Brian Goetz撰写着):
我们通过减少与编写Java代码相关的仪式来提高开发人员的体验,同时保持Java对静态类型安全的承诺,允许开发人员忽略局部变量类型经常不必要的清单声明.
var 在Java中确定范围
应该注意,var它不是Java中的关键字,而是保留类型名称.引自JEP 286:
标识符var不是关键字; 相反,它是一个保留类型名称.这意味着使用var作为变量,方法或包名称的代码不会受到影响; 使用var作为类或接口名称的代码将受到影响(但这些名称在实践中很少见,因为它们违反了通常的命名约定).
需要注意的是,因为var是保留类型名称,而不是一个关键字,它仍然可以用于包名,方法名和变量名(连同其新型干扰作用).例如,以下是varJava 中有效用法的所有示例:
var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;
Run Code Online (Sandbox Code Playgroud)
引自JEP 286:
这种处理将局限于具有初始化器的局部变量,增强的for循环中的索引和传统for循环中声明的局部变量; 它不适用于方法形式,构造函数形式,方法返回类型,字段,捕获形式或任何其他类型的变量声明.
varJava和C#之间的差异
这是varC#和Java 之间的一个显着区别,包括以下内容:var可以在C#中用作类型名称,但不能在Java中用作类名或接口名.根据C#文档(隐式类型局部变量):
如果命名的类型
var在范围内,则var关键字将解析为该类型名称,并且不会被视为隐式类型的局部变量声明的一部分.
var在C#中用作类型名称的能力会产生一些复杂性并引入一些复杂的解决规则,这些规则var在Java中通过禁止var作为类或接口名称来避免.有关varC#中类型名称的复杂性的信息,请参阅限制适用于隐式类型变量声明.有关`var in Java的范围界定决策背后的基本原理的更多信息,请参阅JEP 286:范围选择.
Mar*_*oun 11
它将在JDK 10中得到支持.甚至可以在早期访问构建中看到它的运行情况.
该JEP 286:
增强Java语言以使用初始值设定项将类型推断扩展为局部变量的声明.
所以现在而不是写:
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
Run Code Online (Sandbox Code Playgroud)
你写:
var list = new ArrayList<String>();
var stream = myStream();
Run Code Online (Sandbox Code Playgroud)
笔记:
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 ==> []
Run Code Online (Sandbox Code Playgroud)
一个简单的解决方案(假设您正在使用一个不错的IDE)只是在任何地方键入'int'然后让它为您设置类型.
我实际上刚刚添加了一个名为'var'的类,所以我不必输入不同的东西.
代码仍然太冗长,但至少你不必输入它!
Java 10确实得到了局部变量类型的推断,所以现在它var与C#one相当(据我所知).
它还可以推断出不可表示的类型(程序员无法在该位置命名的类型;尽管哪些类型是不可表示的,但是Java不具有与C#匿名类型相同的类型).
我能找到的一个区别是在C#中,
在Java 10 var中,不是合法的类型名称.
| 归档时间: |
|
| 查看次数: |
107920 次 |
| 最近记录: |