it-swarm.cn

(没有)Java中的属性?

所以,直到最近我才故意让自己保持Java n00b,而我的第一次真实曝光带来了轻微的冲击:Java没有C#风格属性!

好的,我可以忍受。但是,我也可以发誓,我已经在一个代码库中看到了Java中的属性getter/setter代码,但我不记得在哪里。这是怎么实现的?是否有语言扩展?它与NetBeans有关吗?

54
Ishmaeel

Java中的getter和setter有一个“标准”模式,称为 Bean属性 。基本上任何以get开头,不带参数并返回值的方法,都是名为方法名称其余部分的属性的getter属性(带有一个小写的起始字母)。同样set使用单个参数创建一个void方法的setter。

例如:

// Getter for "awesomeString"
public String getAwesomeString() {
  return awesomeString;
}

// Setter for "awesomeString"
public void setAwesomeString( String awesomeString ) {
  this.awesomeString = awesomeString;
}

如果你问的话,大多数Java IDE会为你生成这些方法(在Eclipse中它就像将光标移动到字段并按ctrl-1,然后从列表中选择选项一样简单)。

为了它的价值,为了便于阅读,您实际上也可以使用ishas代替get来获取布尔类型属性,如:

public boolean isAwesome();

public boolean hasAwesomeStuff();
62
Calum

我很惊讶,没有人提到 项目lombok

是的,目前Java中没有属性。还有一些其他缺失的功能。
但幸运的是我们有 项目lombok 正试图改善这种情况。它每天也越来越受欢迎。

所以,如果你使用lombok:

@Getter @Setter int awesomeInteger = 5;

此代码也将生成getAwesomeIntegersetAwesomeInteger。所以它非常类似于 C#自动实现的属性

你可以获得更多关于lombok getters和setters 这里 的信息。
你一定要查看 其他功能 。我最喜欢的是:

Lombok与IDE很好地集成,因此它将显示生成的方法,如果它们存在(建议,类内容,转到声明和重构)。
lombok唯一的问题是其他程序员可能不知道它。你可以随时 delombok 代码,但这是一个解决方法而不是解决方案。

32

“Java Property Support”是针对Java 7提出的,但并未将其纳入语言。

如果感兴趣,请参阅 http://tech.puredanger.com/Java7#property 了解更多链接和信息。

7
Cheekysoft

Bean约定是编写如下代码:

private int foo;
public int getFoo() {
    return foo;
}
public void setFoo(int newFoo) {
    foo = newFoo;
}

在JVM上的一些其他语言中,例如,Groovy,您获得类似于C#的可覆盖属性,例如,

int foo

可以使用简单的.foo访问它,并利用默认的getFoosetFoo实现,您可以根据需要覆盖它们。

6
Hank Gay
public class Animal {

    @Getter @Setter private String name;
    @Getter @Setter private String gender;
    @Getter @Setter private String species;
}

这类似于C#属性。这是 http://projectlombok.org/

6
dantuch

您可能不需要“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());
    }
}
4
LEMUEL ADANE

来自 Jeffrey Richter的 book CLR通过C# :(我认为这些可能是为什么属性仍未在Java中添加的原因)

  • 属性方法可能会抛出异常;字段访问永远不会抛出异常。
  • 属性不能作为outref参数传递给方法;一个领域可以。
  • 属性方法可能需要很长时间才能执行;现场访问总是立即完成。使用属性的一个常见原因是执行线程同步,这可以永久停止线程,因此,如果需要线程同步,则不应使用属性。在那种情况下,一种方法是优选的。此外,如果可以远程访问您的类(例如,您的类派生自System.MarshalByRefObject),则调用属性方法将非常慢,因此,方法优先于属性。在我看来,派生自MarshalByRefObject的类永远不应该使用属性。
  • 如果连续多次调用,则属性方法每次都可以返回不同的值;每次返回相同的值。 System.DateTime类具有readonly Now属性,该属性返回当前日期和时间。每次查询此属性时,它将返回不同的值。这是一个错误,Microsoft希望他们可以通过将Now设置为方法而不是属性来修复该类。 EnvironmentTickCount属性是这个错误的另一个例子。
  • 属性方法可能会导致可观察到的副作用;现场访问永远不会。换句话说,类型的用户应该能够以他或她选择的任何顺序设置由类型定义的各种属性,而不会注意到类型中的任何不同行为。
  • 属性方法可能需要额外的内存或返回对实际上不属于对象状态的内容的引用,因此修改返回的对象对原始对象没有影响;查询字段始终返回对保证属于原始对象状态的对象的引用。使用返回副本的属性可能会让开发人员感到非常困惑,而且这种特性通常没有记录。
3
th1rdey3

如果您需要,Java的大多数IDE都会自动为您生成getter和setter代码。有许多不同的约定,像Eclipse这样的IDE将允许您选择要使用的约定,甚至允许您定义自己的约定。

Eclipse甚至包括自动重构,允许您将属性包装在getter和setter中,它将修改直接访问属性的所有代码,使其使用getter和/或setter。

当然,Eclipse只能修改它所知道的代码 - 任何外部依赖都可能被这种重构打破。

3
Bill Michell

我的Java经验也不是那么高,所以任何人都可以随意纠正我。但AFAIK,一般约定是写两个方法,如下:

public string getMyString() {
    // return it here
}

public void setMyString(string myString) {
    // set it here
}
2
Mark Embling

我只是发布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 {
}

还有更多样本可用,并且生成的代码中没有运行时依赖性。

如果您尝试一下并发现它有用,请给我发送电子邮件! - 斯科特

1
Scott Stanchfield

如果您正在使用Eclipse,那么它具有为内部属性自动生成getter和setter方法的功能,它可以是一个有用且省时的工具。

1
TK.

Java中没有属性关键字(就像你可以在C#中找到的那样)在C++中使用1个Word getter/setter的最近方法是:

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
1
Patrick PIGNOL

如前面提到的Eclipse,集成开发环境(IDE)通常可以自动创建访问器方法。

您也可以使用NetBeans执行此操作。

要为类创建访问器方法,请打开一个类文件,然后右键单击源代码编辑器中的任意位置,并选择菜单命令Refactor,Encapsulate Fields。将打开一个对话框单击“全选”,然后单击“重构”。瞧,

祝好运,

0
levteck