Java有类似C#中“属性(properties)”的功能吗?

26

C#中可以使用属性使数据字段公开访问(允许用户直接访问它),但仍然保留对这些直接访问字段执行数据验证的能力。 Java有类似的功能吗?例如,假设存在一个具有以下实现的C#类(见下文):

public class newInt{

    public newInt(){...}

    public int x{
        get{ return this.x }
        set{ this.x = isValid(value) }
    }
}

private static int isValid(int value){...}

在该类中定义的这个方法允许用户在从数据字段'x'中检索值和给它分配值时使用更加自然的方式。以下是其在主函数中的使用示例。

public class Test{

    public static void main(String[] args){

        newInt a = new newInt();
        a.x = 50;

        int b = a.x;
    }
}

问题是... Java 是否也能做到这一点?如果可以,它叫什么名字?


1
lombok 可以在一定程度上帮助你 - 虽然它不能解决属性语法问题,但确实可以让处理 getter/setter 更加容易。 - Zabba
@Scott,这不是OP所问的。类似的功能(非常相似)已经在Java 5发布后不久由Lombok提供了。 - Jayadevan Vijayan
传统的Java不支持,但Groovy支持。由于它们是兼容的,且几乎所有的Java代码都可以在Groovy中使用,因此如果您需要Java中的属性,这是一种可行的方法。 - Jayadevan Vijayan
5个回答

28

不。

这就是为什么Java有getter/setter方法。

在C#中,通常会有类似以下的代码:

public class SomeObject
{
    private string _title = "";

    public string Title { get { return _title; } set { _title = value; } }
}

或者使用自动属性:
public class SomeObjectAutoProperties
{
    public string Title { get; set; }
}

Java的getter/setter等效方法是:
public class SomeObject
{
    private String _title = "";

    public string getTitle() { return _title; }

    public void setTitle(String value) { _title = value; }
}

20
在现代的C#中,你更有可能会看到public string Title { get; set; } :) - Jon Skeet
6
非常正确。我考虑使用自动属性,但我想展示支持私有字段,所以这里有一个Java的类比。 - Justin Niessner
4
因为如果你使用自动属性,如果发现需要验证,可以随时添加。如果使用公共字段,则会导致破坏性变更。 - Justin Niessner
3
@Oscar,这里在SO上有一堆很好的问题和回答专门解决这个问题。其中一些原因是:你不能将数据绑定到字段,如果你改变主意将变量更改为属性,这将是一个破坏性的更改,反射以一种不同于属性的方式与字段交互,而且(最重要的?)字段不能成为接口的一部分。 - Jeff Sternal
2
@Justin - 我不喜欢使用公共字段的概念,但它似乎不会是一个破坏性的变化;访问同名的公共字段或属性将具有相同的语法。 - Jon Onstott
显示剩余6条评论

7

有Java平台和Java语言两种。

Java语言不支持属性(也许永远不会支持),但是你不必使用Java语言来使用Java平台(就像你不需要坚持使用C#来使用.NET平台一样)。

检查:

和许多其他人。


4
不,你应该使用getter和setter方法。这是Java的惯例。
public class newInt {

    public newInt() {...}

    private int _x = 0;

    public int getX() {
        return this._x;
    }

    public void setX(int x) {
        this._x = isValid(x);
    }
}

2

不,Java没有属性。Java的习惯用法是使用mutator/accessor(getter/setter)。尽管许多人赞成添加它们,但它们不太可能包含在下一个版本(Java 7)中。

有趣的是,JavaFX具有属性。

请记住,当Java诞生时,它从C ++借鉴了许多思想。因此,一些语法和习惯用法与该语言非常相似。


1
同样,C# 也借鉴了 Java 和 Smalltalk :) 哦,你有多可爱的循环啊。 - xximjasonxx

1

没有,它还没有。

我真的有点难以理解这个C#属性,因为我认为其中一个规则是尽可能少地在其中执行代码,而且既然它们已经是公共的了,为什么不使用公共属性呢?

所以,你的Java等效代码(可能很丑)是:

public class NewInt { // In Java class names start with uppercase by convention 
     public int x; 
}

你可以这样使用:

 NewInt ni = new NewInt();
 ni.x = 50;
 int b = ni.x;

我肯定有些东西是缺失的,但大多数情况下这样做就可以了(顺便说一句,我从不像这样编码 :P)

顺便说一句

我并不是很喜欢getter和setter,但我接受它们作为Java惯例的一部分。

我只是希望他们使用这个代替:

 public class NewInt {
     private int x;
     public int x(){ 
         return this.x;
     }
     public void x(int value ) {
         this.x=value;
     }
  }

因此使用方法应该是:

  NewInt a = new NewInt();
  a.x(10);
  int b = a.x();

也许在下一个Java生命周期中。


属性与公共字段并不完全等同,因为在 C# 中访问或修改属性值可以通过方法调用来完成。您可以在获取或设置属性值时包含其他代码。 - serg10
使用 C# 属性或 getter 和 setter 的一个优点(即使您没有在其中放置任何代码)是:您可以选择向它们添加代码,而无需更改任何依赖于您的 API 的代码。 - Rn222

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