Python的property()在Java中的等价方法是什么?

10

我是Java的新手,想要创建一些类变量,在访问时动态计算,就像Python中使用property()方法一样。然而,我不太确定如何描述这个问题,所以在谷歌上搜寻了很多关于Java“Property”类的信息,但这似乎不是同一个东西。Java中与Python的property()方法等效的是什么?


谢谢回复。只是想澄清一下,我知道Java通常鼓励您通过getter和setter访问成员。我的问题是,Java是否允许您访问成员(例如obj.member),并在幕后调用getter/setter,因此执行x = obj.member实际上会执行x = obj.getMember()。 - Cerin
6个回答

9

Java语言本身没有内置此功能。您需要自己编写所有getter和setter。不过,像Eclipse这样的IDE可以为您生成模板代码。

例如:

class Point{
  private int x, y;

  public Point(int x, int y){
    this.x = x;
    this.y = y;
  }

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

  public int getX(){
    return x;
  }

  public void setY(int y){
    this.y = y;
  }

  public int getY(){
    return y;
  }
}

您可能需要查看Project Lombok,它提供了注释@Getter@Setter,这与Python的property有些相似。
使用Lombok,上面的示例可简化为:
class Point{
  @Getter @Setter private int x, y;

  public Point(int x, int y){
    this.x = x;
    this.y = y;
  }
}

这更接近了,但仍然不允许在属性(像属性一样使用)更改时调用动态方法。以下是一些Python代码,通过简单地“设置”URI来调整许多其他对象属性:https://bitbucket.org/russellballestrini/miniuri/src/tip/miniuri.py - user221014
1
你可以使用 @AllArgsConstructor 来进一步消除上述定义构造函数的步骤。 - Nik
@missingfaktor 如果我在一个类中有一个 私有方法 并且我想像一个属性一样在该类中访问它,我该如何实现这个? - Azhar Uddin Sheikh

4

内置的property()函数与这里答案中描述的完全相反。它不是用于为成员变量生成getter和setter。它只允许您通过访问属性来调用方法(因此,尽管您只是访问Python类中的变量,但将调用一个函数)。(此文章解释了如何以及为什么使用它。)
话虽如此,Java没有类似的东西。更重要的是,在Java中不鼓励使用属性访问。我猜您可以在Groovy脚本语言和元编程中实现此功能。但我不知道如何做到这一点。


2

它们并不是真的存在。在Java中,常见做法是将成员声明为privateprotected,并仅通过方法访问它们。这通常会导致大量小型的getFoo()setFoo(newFoo)方法。Python实际上没有privateprotected,更常见的是允许直接访问成员。


1

正如其他人所指出的那样,Java有getter和setter,但没有严格的类比。有一个第三方库叫做Project Lombok,它使用注释在编译时生成.class文件中的getter和setter。这可以用来使代码更简洁。


3
当你没有新的内容可以添加时,应该给已有的答案投赞成票。 - Red Hyena
我的补充是指出了Project Lombok。然后GreyMatter 9.0编辑了他的答案将其包含在内。 - mR_fr0g
不要胡乱指责。我的回答编辑时间(13:18)早于你的回答发布时间(13:33)。 - missingfaktor

0
你想在类中创建新的字段/获取器/设置器吗?如果你想在运行时进行此操作,你需要创建全新的类并将其字段和方法加载到JVM中。为了创建新的类,你可以使用像ASM或CGLib这样的库,但如果你是Java新手,这不是你想要开始尝试的内容。

-1

实际上,您可以在Java中模拟此行为。

警告:下面的解决方案不太美观

您可以编写一个方法在实用程序类中,如下所示:

public Object getProperty(String property, Object obj) {
  if (obj != null && property != null) {
       Field field = obj.getClass().getDeclaredField(property);
       field.setAccessible(true);
       try {
          return field.get(obj);
       } catch (Exception ex) {
          return null;
       }
  }
  return null;
}

你可以将它声明为静态方法,然后将该方法导入到需要这种行为的类中。
顺便说一下,Groovy支持这个特性。

请仔细阅读我的帖子。我不是在寻找一个访问实例成员的函数,而是在寻找一种当我引用实例成员时调用函数的特性。例如: myobj.attribute = 123; 实际上应该是: myobj.setAttribute(123); - Cerin

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