C#中var关键字的一种用法是隐式类型声明。var的Java等效语法是什么?
C#中var关键字的一种用法是隐式类型声明。var的Java等效语法是什么?
Answers:
空无一人。las,您必须输入完整的类型名称。
编辑:发布7年后var
,Java 10中添加了局部变量的类型推断(带有)。
编辑:发布6年后,从下面收集一些评论:
C#之所以使用var
关键字是因为.NET中可能有没有名称的Types。例如:
var myData = new { a = 1, b = "2" };
在这种情况下,不可能给赋予正确的类型myData
。6年前,这在Java中是不可能的(所有类型都有名称,即使它们非常冗长和笨拙)。我不知道这是否已经改变。
var
与dynamic
。var
iable仍然是100%静态键入的。这将无法编译:
var myString = "foo";
myString = 3;
var
当类型从上下文中显而易见时,它也很有用。例如:
var currentUser = User.GetCurrent();
我可以说在我负责的任何代码中currentUser
都有一个User
或派生类。显然,如果您的实现User.GetCurrent
返回一个int,则可能对您不利。
这与无关var
,但是,如果您有奇怪的继承层次结构,在这些层次结构中您将方法与其他方法(例如new public void DoAThing()
)一起使用,请不要忘记非虚拟方法会受到其转换为Type的影响。
我无法想象现实世界中的情况表明良好的设计,但这可能无法按您预期的那样工作:
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;
var p = new X(); p.Z()
与SuperX p = new X(); p.Z()
所有X和SuperX 都不相同X : SuperX
。用var
的静态型的p
是总是X
在上面第一个例子,但总是SuperX
在第二个例子。需要注意的细微但重要的区别。但是您的答案非常正确:-)
var
不会使代码不清楚。我认为恰恰相反。例如,为什么在声明和实例化类型(RadioButton radioButton = new RadioButton();
)时在同一行上写两次(甚至三遍)类型?var
在命名变量时,您宁愿三思而后行,因为这将重点放在功能而不是类型上(例如 UserCollection collection = new userRepository.GetUsers();
,更自然地变成var users = userRepository.GetUsers();
)。如果您认为var
不清楚,那只是因为没有使用它。
var
绝对可以使代码清楚地被很好地使用,但是也可以使代码不清楚地被太坏地使用;像许多格式选项一样 余额的不同取决于您使用匿名对象和泛型的程度(.NET 1.0中都不存在),这使得它在C♯的第一个版本中作为假设关键字的用处较小。RadioButton
radioButton
在工厂或辅助方法的情况下,我只将按钮命名为a ,这是唯一的意义RadioButton
,否则带有或不带有按钮的疯狂var
。
var
你像批评一样,甚至不那么严格,但是我改变了我的观点,也许这就像一个不同观点的问题一样简单,因为当你说这是一个错误时,我仍然认为你是错的无论您使用了多少匿名对象和泛型;)类型声明通常只是代码噪音,如果您不理解它就无法理解代码,则在两种情况下代码都可能不清楚。
如果将Lombok添加到项目中,则可以使用其val关键字。
final
不一定是不变的对象。考虑final StringBuilder strB = new StringBuilder("My reference is final"); strB.append("I'm not immutable");
var
。projectlombok.org/features/experimental/var.html
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>
我已经为IntelliJ制作了一个插件,以某种方式为您提供var
了Java语言。这是一种hack,因此通常的免责声明适用,但是如果您将IntelliJ用于Java开发并想尝试一下,请访问https://bitbucket.org/balpha/varsity。
随着3月20日JDK 10的发布,Java现在包含了JEP 286中var
指定的保留类型名称(不是关键字,请参见下文)。对于局部变量,以下内容现在在Java 10或更高版本中有效:
var map = new HashMap<String, Integer>();
var
Java中的保留类型名称与var
C#中的关键字几乎相同,因为两者都允许隐式键入(有关重要区别,请参见下文)。var
Java中的Java语言只能在以下情况下用于隐式类型推断(如JEP 286:Goals所枚举):
因此var
,不能用于字段,返回类型,类名称或接口名称。它的基本原理是消除声明和定义局部变量时包括长类型名称的需要,如JEP 286 (由Brian Goetz撰写)所述:
我们试图通过减少与编写Java代码相关的仪式来改善开发人员的体验,同时通过允许开发人员取消经常不需要的局部变量类型的清单声明来维护Java对静态类型安全的承诺。
var
Java范围界定应当注意,这var
不是Java中的关键字,而是保留的类型名称。如JEP 286所述:
标识符var不是关键字;而是一个保留的类型名称。这意味着使用var作为变量,方法或程序包名称的代码将不会受到影响;使用var作为类或接口名称的代码将受到影响(但是这些名称在实践中很少见,因为它们违反了通常的命名约定)。
请注意,由于var
它是保留的类型名而不是关键字,因此它仍可用于包名,方法名和变量名(以及其新的类型干扰角色)。例如,以下是var
Java 中有效使用的所有示例:
var i = 0;
var var = 1;
for (var i = 0; i < 10; i++) { /* ... */ }
public int var() { return 0; }
package var;
如JEP 286所述:
这种处理将仅限于带有初始值设定项的局部变量,增强的for循环中的索引以及在传统的for循环中声明的局部变量;它不适用于方法形式,构造函数形式,方法返回类型,字段,catch形式或任何其他类型的变量声明。
var
Java和C 之间的差异这是var
C#和Java 之间的显着区别,包括以下内容:var
可以在C#中用作类型名称,但不能在Java中用作类名称或接口名称。根据C#文档(隐式键入局部变量):
如果
var
范围内有一个名为type的类型,则var
关键字将解析为该类型名称,并且不会被视为隐式键入的局部变量声明的一部分。
var
在C#中用作类型名称的能力会带来一些复杂性,并引入一些复杂的解析规则,而var
在Java中,通过禁止var
使用类或接口名称来避免了这些规则。有关var
C#中类型名称的复杂性的信息,请参见限制适用于隐式类型的变量声明。有关Java中`var的范围界定决定背后的基本原理的更多信息,请参见JEP 286:范围选择。
var
用于字段或返回类型?为什么要注意很重要?
var
Java中的不能用于字段或返回类型。这很重要,因为此限制使var
上下文敏感,该限制只能在某些上下文(局部变量)中使用,而不能在其他上下文中使用。这并不一定是Java和C#之间的区别,而是var
在Java中使用时通常的重要限制。
var
一个类名并按原样使用它。从技术上讲,对于c#,它是一个“上下文关键字”,但是在Java中,看来您不能做同样的事情。如我错了请纠正我。
var
在Java中用作类名或接口名(无论如何并不常见),但是可以将其用于变量名,方法名和程序包名。例如,var var = 1;
是有效的Java语句,但是尝试将类声明为public class var {}
错误:as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations
。我已经更新了上面的答案,以更详细地了解var
Java 背后的原理及其与var
C#的区别。
JDK 10将支持它。甚至可以在早期访问版本中看到它的实际应用。
该JEP 286:
增强Java语言,以使用初始化程序将类型推断扩展到局部变量的声明。
所以现在不用写:
List<> list = new ArrayList<String>();
Stream<> stream = myStream();
你写:
var list = new ArrayList<String>();
var stream = myStream();
笔记:
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 ==> []
var
)并不等效。在var
示例中list
是类型ArrayList
,而不是List
。
一个简单的解决方案(假设您使用的是一个不错的IDE)是在任何地方键入'int',然后为您设置类型。
实际上,我只是添加了一个名为“ var”的类,因此不必键入其他内容。
该代码仍然太冗长,但是至少您不必键入它!
int
)–我是否缺少某些东西?(*:虽然我永远都不会将Eclipse称为一个像样的IDE,但我无法判断其他人……)
Java 10确实获得了局部变量类型推断,所以现在它具有var
与C#相当的功能(据我所知)。
它也可以推断出非denotable类型(类型的不能用程序员的地点进行命名;虽然这类型为非denotable是不同的)。参见例如带有var
和匿名类的技巧(您永远不要在工作中使用)。
我可以找到的一个区别是在C#中,
在Java 10 var
中不是合法的类型名称。
由于Java的10,相当于是... var
。
我知道这比较老,但是为什么不创建一个var类并创建具有不同类型的构造函数,并根据调用的构造函数的不同而得到具有不同类型的var。您甚至可以建立将一种类型转换为另一种类型的方法。
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);
这是一个陷阱,以避免试图使用它的时候IntelliJ IDEA
。尽管包括自动完成功能和所有功能,它似乎都能按预期工作。直到有一个“非hacky”解决方案为止(例如,由于JEP 286:本地变量类型推断)),这可能是您目前最好的选择。
请注意,val
它Lombok
也无需修改或创建即可提供支持lombok.config
。
您可以使用Java 10,但仅适用于本地变量,也就是说,
您可以,
var anum = 10; var aString = "Var";
但是不能
var anull = null; // Since the type can't be inferred in this case
查看规范以获取更多信息。
var
可用于多种形式的不可表示类型,包括捕获类型,交集类型和匿名类类型。并且,从Java 11开始,它也可以应用于lambda参数。
通常,您可以将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);
var
该词已正式成为该语言的用语,您的答案也指的是老式的方式。
Java SE 10现在提供了此功能。静态,类型安全的var终于进入了Java世界:)
来源:https : //www.oracle.com/corporate/pressrelease/Java-10-032018.html
val
(或var
)如果您使用特定的“ Java替换”语言;-)