所以,直到最近,我才任性地给自己留了一个Java n00b,而我第一次真正的曝光带来了一个小小的震惊:Java 没有C# 风格的属性!
好吧,我可以忍受。但是,我也可以发誓,我在一个代码库中看到了 Java 中的属性 getter/setter 代码,但我不记得在哪里。那是如何实现的?有语言扩展吗?它与NetBeans有关吗?
所以,直到最近,我才任性地给自己留了一个Java n00b,而我第一次真正的曝光带来了一个小小的震惊:Java 没有C# 风格的属性!
好吧,我可以忍受。但是,我也可以发誓,我在一个代码库中看到了 Java 中的属性 getter/setter 代码,但我不记得在哪里。那是如何实现的?有语言扩展吗?它与NetBeans有关吗?
Java 中有一个用于 getter 和 setter 的“标准”模式,称为Bean properties。基本上任何get
以 . 同样set
,使用单个参数创建 void 方法的设置器。
例如:
// Getter for "awesomeString"
public String getAwesomeString() {
return awesomeString;
}
// Setter for "awesomeString"
public void setAwesomeString( String awesomeString ) {
this.awesomeString = awesomeString;
}
如果您提出要求,大多数 Java IDE 都会为您生成这些方法(在 Eclipse 中,只需将光标移动到某个字段并点击Ctrl- 1,然后从列表中选择选项)。
对于它的价值,为了可读性,您实际上也可以使用is
并has
代替get
布尔类型的属性,如:
public boolean isAwesome();
public boolean hasAwesomeStuff();
我很惊讶没有人提到龙目岛项目
是的,目前java中没有属性。还有一些其他缺失的功能。
但幸运的是,我们有项目 lombok正在努力改善这种情况。它每天也越来越受欢迎。
因此,如果您使用的是 lombok:
@Getter @Setter int awesomeInteger = 5;
getAwesomeInteger
这段代码也将生成setAwesomeInteger
。所以它与C# 自动实现的属性非常相似。
您可以在此处获取有关 lombok getter 和 setter 的更多信息。
您绝对应该检查其他功能。我最喜欢的是:
Lombok 与 IDE 完美集成,因此它将显示生成的方法,例如它们是否存在(建议、类内容、转到声明和重构)。
lombok 的唯一问题是其他程序员可能不知道它。您始终可以对代码进行delombok,但这与其说是解决方案,不如说是一种解决方法。
为 Java 7 提出了“Java 属性支持”,但没有将其纳入语言。
如果有兴趣,请参阅http://tech.puredanger.com/java7#property了解更多链接和信息。
bean约定是这样写代码:
private int foo;
public int getFoo() {
return foo;
}
public void setFoo(int newFoo) {
foo = newFoo;
}
在 JVM 上的其他一些语言中,例如 Groovy,您可以获得类似于 C# 的可覆盖属性,例如,
int foo
它可以通过简单的方式访问,.foo
并利用您可以根据需要覆盖的默认值getFoo
和setFoo
实现。
public class Animal {
@Getter @Setter private String name;
@Getter @Setter private String gender;
@Getter @Setter private String species;
}
这类似于 C# 属性。这是http://projectlombok.org/
你可能不需要“get”和“set”前缀,为了让它看起来更像属性,你可以这样做:
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());
}
}
如果您愿意,大多数 Java IDE 会自动为您生成 getter 和 setter 代码。有许多不同的约定,像 Eclipse 这样的 IDE 将允许您选择要使用的约定,甚至可以让您定义自己的约定。
Eclipse 甚至包括自动重构,它允许您将属性包装在 getter 和 setter 中,并且它将修改直接访问该属性的所有代码,以使其使用 getter 和/或 setter。
当然,Eclipse 只能修改它知道的代码——您拥有的任何外部依赖项都可能被这种重构破坏。
我的 Java 经验也不是那么高,所以任何人都可以随时纠正我。但是 AFAIK,一般惯例是编写两种方法,如下所示:
public string getMyString() {
// return it here
}
public void setMyString(string myString) {
// set it here
}
来自Jeffrey Richter 的 书CLR via C#:(我认为这些可能是 JAVA 中仍未添加属性的原因)
out
或ref
参数传递给方法;一个字段可以。System.MarshalByRefObject
),调用属性方法会很慢,因此,方法比属性更受欢迎。在我看来,派生自的类不
MarshalByRefObject
应该使用属性。System.DateTime
有一个只读
Now
属性,它返回当前日期和时间。每次查询此属性时,它都会返回不同的值。这是一个错误,Microsoft 希望他们可以通过将 Now 设为方法而不是属性来修复该类。Environment
的
TickCount
属性是这个错误的另一个例子。如果您使用的是 eclipse,那么它可以自动为内部属性生成 getter 和 setter 方法,它可以是一个有用且省时的工具。
我只是发布 Java 5/6 注释和一个注释处理器来帮助解决这个问题。
查看http://code.google.com/p/javadude/wiki/Annotations
文档现在有点轻,但是 quickref 应该可以理解。
基本上,它使用 getter/setter(以及许多其他代码生成选项)生成一个超类。
示例类可能看起来像
@Bean(properties = {
@Property(name="name", bound=true),
@Property(name="age,type=int.class)
})
public class Person extends PersonGen {
}
还有更多可用的示例,并且生成的代码中没有运行时依赖项。
如果您尝试并发现它有用,请给我发送电子邮件!——斯科特
java 中没有属性关键字(就像你可以在 C# 中找到它一样),拥有 1 个单词 getter/setter 的最接近的方法是像在 C++ 中一样:
public class MyClass
{
private int aMyAttribute;
public MyClass()
{
this.aMyAttribute = 0;
}
public void mMyAttribute(int pMyAttributeParameter)
{
this.aMyAttribute = pMyAttributeParameter;
}
public int mMyAttribute()
{
return this.aMyAttribute;
}
}
//usage :
int vIndex = 1;
MyClass vClass = new MyClass();
vClass.mMyAttribute(vIndex);
vIndex = 0;
vIndex = vClass.mMyAttribute();
// vIndex == 1
正如前面提到的 Eclipse,集成开发环境 (IDE) 通常可以自动创建访问器方法。
您也可以使用 NetBeans 来完成。
要为您的类创建访问器方法,请打开一个类文件,然后右键单击源代码编辑器中的任意位置并选择菜单命令 Refactor、Encapsulate Fields。将打开一个对话框。单击全选,然后单击重构。瞧,
祝你好运,
对我来说,问题有两个方面:
public class Test {
private String _testField;
public String testProperty {
get {
return _testField;
}
set {
_testField = value;
}
}
}
public class TestUser {
private Test test;
public TestUser() {
test = new Test();
test.testProperty = "Just something to store";
System.out.printLn(test.testProperty);
}
}
这是我想重新使用的那种简单的任务。不必使用“方法”调用语法。任何人都可以提供一些关于 Java 发生了什么的答案吗?
我认为问题还在于代码中不必要的混乱,而不是创建 setter/getter 的“困难”。我认为它们是丑陋的代码。我喜欢 C# 所拥有的。我不理解将这种功能添加到 Java 中的阻力。
我目前的解决方案是在不需要保护时使用“公共”成员:
public class IntReturn {
public int val;
}
public class StringReturn {
public String val;
}
这些将用于从 Lambda 中返回值:
StringReturn sRtn = new StringReturn()
if(add(2, 3, sRtn)){
System.out.println("Value greater than zero");
}
public boolean add(final int a, final int b, final StringReturn sRtn){
int rtn = a + b;
sRtn.val = "" + rtn;
return rtn > 0; // Just something to use the return for.
}
我也真的不喜欢使用方法调用来设置或获取类的内部值。
如果您的信息作为“不可变”传输,那么新的 Java记录可能是一个解决方案。但是,它仍然使用 setter/getter 方法,只是没有 set/get 前缀。