English 中文(简体)
(否)Java中的财产?
原标题:
  • 时间:2008-09-16 08:52:01
  •  标签:

所以,直到最近,我一直故意将自己保存为一个Java n00b,而我第一次真正接触Java带来了一个小小的震惊:Java没有C#风格的财产!

好吧,我可以接受。然而,我也可以发誓,我在一个代码库中看到了Java中的属性getter/setter代码,但我不记得在哪里。这是如何实现的?有语言扩展吗?它和NetBeans有关吗?

最佳回答

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;
}

如果您提出要求,大多数JavaIDE都会为您生成这些方法(在Eclipse中,这很简单,只需将光标移动到一个字段,然后点击Ctrl-1,然后从列表中选择选项)。

值得一提的是,为了可读性,您实际上可以使用is,并且对于布尔类型的财产,get也可以使用>来代替,如:

public boolean isAwesome();

public boolean hasAwesomeStuff();
问题回答

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

Yes, currently there are no properties in java. There are some other missing features as well.
But luckily we have project lombok that is trying to improve the situation. It is also getting more and more popular every day.

因此,如果您正在使用lombok:

@Getter @Setter int awesomeInteger = 5;

此代码还将生成getAwesomeIntegersetAwesomeIntegerC#自动实现的财产。

You can get more info about lombok getters and setters here.
You should definitely check out other features as well. My favorites are:

Lombok is well-integrated with IDEs, so it is going to show generated methods like if they existed (suggestions, class contents, go to declaration and refactoring).
The only problem with lombok is that other programmers might not know about it. You can always delombok the code but that is rather a workaround than a solution.

“Java属性支持”是为Java 7提出的,但没有成为该语言。

请参阅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访问,并利用默认的getFoosetFoo实现,您可以根据需要覆盖这些实现。

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)的《通过C#的CLR》(CLR)一书:(我认为这可能是JAVA中仍然没有添加财产的原因)

  • A property method may throw an exception; field access never throws an exception.
  • A property cannot be passed as an out or ref parameter to a method; a field can.
  • A property method can take a long time to execute; field access always completes immediately. A common reason to use properties is to perform thread synchronization, which can stop the thread forever, and therefore, a property should not be used if thread synchronization is required. In that situation, a method is preferred. Also, if your class can be accessed remotely (for example, your class is derived from System.MarshalByRefObject), calling the property method will be very slow, and therefore, a method is preferred to a property. In my opinion, classes derived from MarshalByRefObject should never use properties.
  • If called multiple times in a row, a property method may return a different value each time; a field returns the same value each time. The System.DateTime class has a readonly Now property that returns the current date and time. Each time you query this property, it will return a different value. This is a mistake, and Microsoft wishes that they could fix the class by making Now a method instead of a property. Environment’s TickCount property is another example of this mistake.
  • A property method may cause observable side effects; field access never does. In other words, a user of a type should be able to set various properties defined by a type in any order he or she chooses without noticing any different behavior in the type.
  • A property method may require additional memory or return a reference to something that is not actually part of the object’s state, so modifying the returned object has no effect on the original object; querying a field always returns a reference to an object that is guaranteed to be part of the original object’s state. Working with a property that returns a copy can be very confusing to developers, and this characteristic is frequently not documented.

如果您使用eclipse,那么它可以自动生成内部属性的getter和setter方法,这是一个有用且节省时间的工具。

我刚刚发布了Java5/6注释和一个注释处理器来帮助实现这一点。

查看http://code.google.com/p/javadude/wiki/Annotations

文档现在有点轻,但quickref应该能让人理解这个想法。

基本上,它生成了一个包含getters/ssetter(以及许多其他代码生成选项)的超类。

示例类可能看起来像

@Bean(properties = {
    @Property(name="name", bound=true),
    @Property(name="age,type=int.class)
})
public class Person extends PersonGen {
}

还有更多的示例可用,并且在生成的代码中没有运行时依赖项。

Send me an email if you try it out and find it useful! -- Scott

java中没有property关键字(就像你在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来完成。

To create accessor methods for your class, open a class file, then Right-click anywhere in the source code editor and choose the menu command Refactor, Encapsulate Fields. A dialog opens. Click Select All, then click Refactor. Voilà,

祝你好运

对我来说,问题有两个方面:

  1. All these extra methods {get*/set*} cluttering up the class code.
  2. NOT being able to treat them like properties:
    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<strong>记录可能是一个解决方案。然而,它仍然使用setter/getter方法,只是没有set/get前缀。





相关问题