使用公共方法更改 Java 中的私有字段

Changing private fields in Java using public methods

本文关键字:字段 Java 方法      更新时间:2023-10-16

在C++中,有一种方法可以更改数据,即使它是私有的:

class Foo
{
private:
    char * i;
public:
    char * getInt() {return i;};
    Foo() {i="Winter";};
}
int main()
{
  Foo a;
  strcpy(a.getInt(), "Summer"); //it changes i
  cout<<a.getInt(); //gives "Summer"
  return 0;
}

有没有办法在Java中做到这一点?

编辑:如果有,那么是否有一些关键字,如C++中的const,以防止这种行为?

Java 返回指向对象的指针副本(以及原语值的副本)。String就是这样一个对象。例如

class Foo {
    private String i = "Winter";
    public String get() { return i; }
}

现在这是完全安全的,没有什么(除了反射)可以改变你的私人领域或其状态:

void main() {
  Foo a = new Foo();
  String i = a.get();
  String j = i + " rocks"; // creates a new string
  i = "Summer"; // now points to another string
  System.out.println(a.get()); // still prints "Winter"
}

但是,如果代码能够修改返回的对象,则无法阻止它更改它。

Java也没有使对象不可变的内置方法,您必须将它们设计为实际上不可变的,例如String类。每个"修改"字符串的方法实际上都会创建一个新的不可变字符串,该字符串可以在所有位置和线程之间共享,而无需担心。

如果你的班级是

class Foo {
    public String i = "Winter";
}

你不会安全的。代码可以更改该字段指向的内容。

void main() {
  Foo a = new Foo();
  a.i = "Summer"; // that works.
  System.out.println(a.i); // prints "Summer"
}

虽然您不应该拥有公共字段,特别是如果您不希望对其进行修改,但有一些帮助:final

class Foo {
    public final String i = "Winter";
}
void main() {
  Foo a = new Foo();
  a.i = "Summer"; // Error: final field cannot be modified.
}

final 关键字保证一个字段只分配一次。该字段在构造函数完成后需要具有值,并且之后无法更改。但是,引用的对象可能仍然是可变的,只是对它的引用不是可变的。