C#具有声明和使用属性的语法。例如,可以声明一个简单的属性,如下所示:
public int Size { get; set; }
还可以在属性中添加一些逻辑,如下所示:
public string SizeHex
{
get
{
return String.Format("{0:X}", Size);
}
set
{
Size = int.Parse(value, NumberStyles.HexNumber);
}
}
无论是否具有逻辑,属性的使用方式与字段相同:
int fileSize = myFile.Size;
我对Java或C#并不陌生 - 我已经使用了很多,而且我总是错过了Java中的属性语法。我在this question读到“在Java 7中或者可能永远不会添加属性支持”,但坦率地说,我发现在讨论,论坛,博客,评论和JSR中挖掘太多工作了。找出原因。
所以我的问题是:有人可以总结为什么Java不太可能获得属性语法吗?
答案 0 :(得分:13)
我认为这只是Java对事物的一般哲学。属性有点“神奇”,Java的理念是尽可能简化核心语言,避免像瘟疫那样的魔法。这使得Java成为通用语言,几乎任何程序员都可以理解。它还可以很容易地推断出任意孤立的代码片段正在做什么,并且能够提供更好的工具支持。缺点是它使语言更冗长,更不具有表现力。这不一定是设计语言的正确方法或错误方法,这只是一种权衡。
答案 1 :(得分:9)
10年左右,sun尽可能地抵制语言的任何重大变化。在同一时期,C#已经通过一个引人注目的开发,为每个版本添加了许多新的酷功能。
我认为很久以前火车离开了java中的属性,它们会很好,但是我们有java-bean规范。现在添加属性只会使语言更加混乱。虽然javabean规范IMO远没有那么好,但它必须要做。在宏伟的事物计划中,我认为物业并不是那么相关。 java代码中的膨胀是由getter和setter之外的其他东西引起的。
有更重要的事情要关注,例如获得一个体面的关闭标准。
答案 2 :(得分:7)
C#中的属性语法只不过是syntactic sugar。你不需要它,它只是为了方便。 Java人不喜欢语法糖。这似乎足以让它缺席。
答案 3 :(得分:3)
可能的论据只基于我不知情的意见
我实际上喜欢那些属性的语法糖,因为整个语法往往会混淆代码,这在概念上非常简单。 Ruby似乎没有太大惊小怪。
另一方面,我实际上试图编写一些没有属性访问权限的中型系统(几十个类),这只是因为减少了混乱和代码库的大小。除了不安全的设计问题(我愿意在这种情况下捏造)这几乎是不可能的,因为每个框架,每个库,每个Java中的所有内容都通过get和set方法自动发现属性。他们和我们一起直到非常时间的结束,有点像语法训练轮。
答案 4 :(得分:1)
可能对添加到Java很有用,但它可能不像闭包那样高。
就个人而言,我发现一个体面的IDE使这个问题没有实际意义。 IntelliJ可以为我生成所有的getter / setter;我所要做的就是将你所做的行为嵌入到方法中。我认为这不是一个交易破坏者。
我承认我对C#并不了解,所以也许那些将会推翻我的人。这只是我的意见。
答案 5 :(得分:1)
我会说它反映了语言变化的缓慢。正如之前的一位评论者所提到的,现在大多数IDE都没有那么大的优惠。但是没有JVM特定的理由让它不在那里。
答案 6 :(得分:1)
如果我不得不猜测,我会说它与语法糖的哲学反对意见较少(他们添加了自动装箱,增强了循环,静态导入等 - 所有糖)而不是向后兼容性问题。至少到目前为止,Java人员已经非常努力地设计新的语言功能,以便保持源级向后兼容性(即为1.4编写的代码仍然可以编译和运行,无需在5或6中进行修改或以后)。
假设他们引入了属性语法。那么,以下是什么意思:
myObj.attr = 5;
这取决于你是在谈论在添加属性特性之前或之后编写的代码,还可能是关于类本身的定义。
我并不是说这些问题无法解决,但我怀疑它们是否能够以一种导致清晰,明确的语法的方式解决,同时保留与以前版本的源兼容性。
python人员可能会破坏旧代码,但这不是Java的方式......
答案 7 :(得分:0)
这与他们不改变Java中的任何其他内容的原因相同 - 向后兼容性。
答案 8 :(得分:0)
- 是否因为与其他可能的改进相比,它被认为不够重要?
这是我的猜测。
- 是否存在技术(例如与JVM相关)的限制?
没有
- 这是政治问题吗? (例如“我已经用Java编写了50年的代码,我说:我们不需要steenkin'属性!”)
最有可能。
- 是否是自行车的情况?
呃?
Java的主要目标之一是保持语言简单。
来自:Wikipedia
Java为了简化语言并防止可能的错误和反模式设计而抑制了类的几个功能。
答案 9 :(得分:0)
以下是一些逻辑,对我来说,导致不喜欢某种语言的属性:
一些编程结构被使用,因为它们存在,即使它们支持错误的编程实践。
Setters意味着可变对象。可以轻易使用的东西。
良好的OO设计要求对象做一些业务逻辑。属性意味着您要求数据并自行处理数据。
虽然你可以覆盖setter和getters中的方法,但很少有人这样做;最后一个公共变量也与getter完全相同。因此,如果你没有可变对象,那就是一个有争议的问题。
如果您的变量具有与之关联的业务逻辑,则逻辑应该通常与变量一起位于类中。如果它没有,为什么在世界上它是一个变量???它应该是“数据”并且在数据结构中,因此可以通过通用代码进行操作。
我相信Jon Skeet指出C#有一种处理这种数据的新方法,数据应该是编译时输入的,但实际上不应该是变量,而是因为我的世界与C#世界的交互很少,我会接受他的说法,这很酷。
此外,我完全接受,根据您的风格和您与之交互的代码,您必须时不时地设置/获取情况。我仍然在每一两个阶段平均一个二传手/吸气剂,但还不足以让我觉得一个新的编程结构是合理的。
请注意,我对工作和家庭编程的要求非常不同。对于我的代码必须与其他20个人的代码交互的工作,我认为结构更明确,更好。在家里Groovy / Ruby很好,属性也很棒等等。
答案 10 :(得分:0)
根据Core Java第2卷(忘记了作者,但它是一本非常受欢迎的书),语言设计者认为隐藏字段访问语法背后的方法调用是一个不好的主意,因此将其排除在外。
答案 11 :(得分:0)
你可能不需要"得到"和"设置"前缀,使它看起来更像属性,你可以这样做:
public class Person {
private String firstName = "";
private Integer age = 0;
public String firstName() { return firstName; } // getter
public void firstName(String val) { firstName = val; } // setter
public Integer age() { return age; } // getter
public void age(Integer val) { age = val; } //setter
public static void main(String[] args) {
Person p = new Person();
//set
p.firstName("Lemuel");
p.age(40);
//get
System.out.println(String.format("I'm %s, %d yearsold",
p.firstName(),
p.age());
}
}