为什么Java没有像C#那样的自动属性?

23

C#有自动属性可以极大地简化您的代码:

public string Name { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }

相比较Java需要写如下的代码:

private String name;
private String middleName;
private String LastName;

public String Name(){
   return this.name;
}

etc..

Java为什么没有实现类似这样的东西?


15
就算价值不高,既然是在Java中,你应该把方法命名为getName、setName等等。这样能够在许多Java IDE的设计器中设置属性。更何况如果Java有了属性,我几乎可以保证这些规范将成为其中的一部分,以使所有现有的bean都能神奇地变成属性。 - cHao
4
顺便提一下,C# 直到(相对较近的)最近才拥有自动属性。 - Brian S
7
这是毫无意义的问题。你需要问Java的设计者、现任产品经理或Java社区流程,而不是www.stackoverflow.com。 - user207421
@BrianS - 那不是在2.0版(2005年)吗?那已经是7年前了(或者在你发表评论时是5年前)。但这显示了Java和C#之间最大的区别,也可能是回答这个问题的答案,即C#作为一个产品被设计得比Java更快地改变和发展。 - Hogan
5个回答

20

没错,因为它并没有这个功能。俗话说得好,“所有功能最初都是未实现的。”


1
@finnw:我完全同意这里的投票策略是有问题的,但我的答案是正确的。Jesper的回答更详细,但他发表得更晚。把你的仇恨带到元论坛去吧。 - Noon Silk
1
这不是仇恨,而是我对投票反对的理由。我已经在元社区中说了很多关于这个问题的话。 - finnw
@finnw:说得好,我理解你的解释,但我不想参与任何关于这个网站的元论争议。 - Noon Silk

19

向现有编程语言添加新功能并不容易,尤其是如果你关心向后兼容性。Sun一直非常小心地向Java添加新功能,因为他们想确保任何新语言功能都不会破坏多年来编写的数百万Java程序。

因此,这不仅仅是将其添加到语言中的问题; 您必须仔细考虑并尝试使用新功能,以发现是否存在任何微妙的向后兼容性问题。

已经提出了各种形式的在Java中支持属性的建议,但看起来在Java 7(即将推出的下一个版本)中,不考虑此功能。

您可能需要查看 Project Lombok ,它是Java的一种扩展,使用注释使编写更简洁的代码成为可能(例如,它可以自动生成字段的getter和setter)。


1
+1 Lombok的@Data还会添加toString,equals和hashcode方法。 - stacker
1
这些事情是真实的,但这些是C#团队所做的事情,而Java团队没有做的事情。C#是否曾经引入过破坏性变更?我觉得这并没有充分回答关于自动属性的问题,这个答案可能更多地与项目方向、资源和领导力有关。 - Greg

3

自动属性基于属性。

C#中的属性是一种语言特性,在Java中它们是一种约定(以get或set开头的方法通常被认为是属性,但对编译器来说与foo或bar没有区别)。

.NET及其相关语言在很多方面都基于COM(有时遵循,在COM中故意不做某些出于某种原因不受欢迎的事情)。

COM具有属性的概念,在VB中得到了语言特性的支持(在C++中则通过约定实现)。

早期的VB特别是在用于提供从其他地方获取的对象模型的基本编程访问时,旨在简化呈现给用户的对象模型,以使字段和获取或设置属性(可能需要额外工作,也可能不需要)之间的区别变得不重要(请考虑一下,虽然它们在.NET中在某些重要方面与外部不同,但在语法上访问属性和公共字段是相同的)。当VB和COM(甚至OLE之前)发展起来时,它们是一起成长的。

因此,虽然C#与Java共享C / C ++继承关系,但它也有Java所没有的继承关系,这使属性看起来对C#的创建者来说是一个好主意,但对Java的创建者来说却不是。

编辑:起初我说:


个人认为,自动属性实际上是对属性缺陷的一种解决方法,而不是简化代码的一种方式。在语法上,“属性”看起来像公共字段,但并非完全相同(尝试使用检索字段)。如果一个属性既完全公开,又在getter或setter中没有其他功能(这是自动属性的情况),我宁愿只有一个公共字段(封装在这里没有争议,因为完全将其公开可以绕过它),但字段和属性之间的区别反对这样做。


我撤回了那个声明。使字段完全像属性将导致简单的POD结构体的字段行为像属性,这会降低性能。从概念上讲,我希望它们更像彼此,但每当我考虑它时(我已经不止一次因此而烦恼,然后像这里一样想到“哦等等”),事实证明它现在比较好。


1

.Net在Java之后出现,其目标之一是与COM互操作。 COM具有属性,可能是VB的方式,因此为了使语言互操作,.net几乎不得不添加它们。 (那样做还有一个相当棒的想法。)

Java没有这样的需求,它的创建者可能不想污染“=”的含义或使函数调用看起来像成员变量。(他们至少曾经非常注重保持语言尽可能干净。)他们的方法是Java bean规范,指定了getter和setter的命名约定。 知道规范的IDE可以将getter和setter的视图“伪装”为单个“属性”以进行设计。


1
由于同样的原因,C# 2.0或更低版本没有这个功能。它更多的是语法糖而不是语言特性。有很多类似的功能可以添加到任何语言中,但是没有人知道为什么它们不是语言的一部分。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接