【问题标题】:Access private property without get/set [duplicate]无需获取/设置即可访问私有财产[重复]
【发布时间】:2012-12-02 13:08:51
【问题描述】:

可能重复:
Absence of property syntax in Java

看下面的情况:

class Test extends Object {
    private int x;
    public getX() {return x;}
    public setX(int _x) {x = _x;}
}

如您所见,没什么特别的。但是,我想知道是否有可能以使用该类的人不需要使用 getX() 的方式保留“私有 x”,换句话说,如果我可以映射一些自动调用的变量获取和设置。

类似于 Delphi 中的“属性”。它可以避免在复杂的表达式中使用 setX() 和 getX() 并且可以更容易理解谁在读取表达式。

例如,假设可以使用另一个标识符 xx 和 yy 来代替 get 和 set 方法。见:

import Test;
public static void main(String[] args) {
    new Test() {
        setX(10);
        setY(20);
        int z = getX() * getY() + (getY() * getY());
        System.out.println("%d", z);
    }
    // would be like this
    new Test() {
        xx = 10;
        yy = 20;
        int z = xx * yy + (yy * yy); // xx would access the method getX() automatically
        System.out.println("%d", z);
    }
}

希望你们明白我的意思。

编辑:

卷起绉纱!这是很多答案!非常感谢大家。

【问题讨论】:

  • 在 Java 中,强烈建议将变量设为私有并使用 get/set 访问而不是直接使用。如果您的子类具有相同的属性名称,您可能会看到这种方法的优势。
  • 或者如果你有充分的理由不这样做,就公开
  • 要么您希望它是私有的,要么您不希望它是私有的。如果您希望它是私有的,您不希望访问其他类。如果您想访问其他课程,请不要将其设为private
  • @Nambari 如果您的子类具有相同的 method 名称怎么办?那更糟。

标签: java properties encapsulation private-members


【解决方案1】:

您可以使用反射访问它们,

Test test = new Test()
Field field = test.getClass().getDeclaredField("x");
field.setAccessible(true);

System.out.println(field.getName() + "="+field.get(test ));

但是,你不应该这样做

【讨论】:

  • 什么是“f”?只要我只是在测试课程,为什么不应该这样做?
  • @AbdalrahmanShatou 我修复了我的代码,f 应该是字段,x 应该是你正在阅读的对象的实例
  • 如果您通过反射获取私有字段的值进行测试,就可以了
【解决方案2】:

你不能。

这就是我们谈论“封装”的原因。仅当您将私有更改或修改为其他内容或使用反射时(这会使它变得更加复杂)。

我认为使用著名的 getter 和 setter 没有任何问题。

【讨论】:

  • 你错了。你可以 !在某些情况下,您想要访问私有字段。例如单元测试。
【解决方案3】:

我认为您正在尝试像 C# 属性一样将其理想化,就像以下代码一样,对吧?:

public sealed class Example {
    private int _code;
    private string _name;

    public Example(int code) {
        this._code = code;
    }

    public int Code {
        get {return this._code;}
        set {this._code = value;}
    }

    public string Name {
        set {this._name = value;}
        get {return this._name;}
    }

    public override string ToString() {
        return this._code.ToString();
    }
}

到目前为止,在 Java 中我相信我们没有这样的手段,但我也认为使用 getter 和 setter 没有什么问题。

【讨论】:

    【解决方案4】:

    您最多可以将privateprotected 切换,因此无论继承它都可以直接访问它。

    但是,是的,你真的不能。此属性与方法相关联。它必须在 Java 中使用括号 ()。在 Java 中“还”没有办法做到这一点,它必须是某种指向方法的指针。

    【讨论】:

      【解决方案5】:

      拥有 getter 和 setter 已经在精神上打破了封装,所以不要犹豫使用公共字段。 “总有一天你会想要在你的 setter 中得到验证,你会感谢自己做出有远见的决定来拥有它们”这个论点表面上看起来似乎是合理的,但实际上这只是一个孩子的故事。在我的职业生涯中,我写了几千个二传手;以后从来没有一个必须添加验证。如果有验证,它总是在外面发生。这将验证与数据分离,并为每个用例允许不同的规则。

      另一个想法是保留方法,但使名称真正简短:int x()void x(int x)

      【讨论】:

        【解决方案6】:

        想想将来你将不允许为将使用你的变量 x 的 x 用户输入负值。在这种情况下,您必须通过验证更改 setX,并且已经使用该方法的人不会受到影响,这就是封装。因此,强烈建议您在进行私有声明时使用公共 getter 和 setter。

        【讨论】:

          【解决方案7】:

          我会试着解释一下……

          class Test extends Object

          首先你不要必须使用Test extends Object。每当你don't or do explicitly extends your class to any other class, it will always extend the Object Class, directly or indirectly.

          - 现在回答您的问题,您在这里看到的最简单和最基本的形式称为Encapsulation。在Java 中,你不能像在Delphi or .Net 中那样做。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-06-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-10-07
            • 2016-10-16
            • 1970-01-01
            相关资源
            最近更新 更多