私有静态字段 Java

huangapple go评论83阅读模式
英文:

private static field Java

问题

以下是翻译好的部分:

  1. A 是不可变的。
  2. A 不一定是不可变的,因为它可能扩展了一个不可变的类。
  3. A 不一定是不可变的,因为你可能能够从静态方法中更改它的字段。

为什么如果所有字段都是私有的,仍然可以修改字段呢?
如果它扩展了一个不可变的类,但仍然将所有内容保持私有,它可能是不可变的吗?
从静态方法中更改其字段是什么意思?

英文:

I was asked the following question:

Assuming all instance fields and all instance methods of class A in Java are private, which of the following are correct:

  1. A is immutable
  2. A is not for sure immutable because it could be that it extends a not-immutable class
  3. A is not for sure immutable because you might be able to change its fields from static methods

I thought the correct answer was 1 but turns out 2 and 3 are both correct and 1 is not.

How come if everything is private you can still modify the fields?

Why if it extends a not immutable class, but still have everything private, it might be now immutable?

What does it mean to change its fields from static methods?

答案1

得分: 1

可以扩展一个具有公共字段的类,在这种情况下,尽管A本身没有定义任何可变字段,但这些字段可以被修改,因为它将继承其父类的字段和实例方法。

考虑以下代码:

class Child extends Parent {
    private String name;
}
class Parent {
    public int id;
}
class TestChild {
    public static void main(final String[] args) {
        final Child child = new Child();
        //String s = child.name; <--Child.name字段不可见
        System.out.println("Previous id: " + child.id);
        child.id = 100; //<--我们可以修改它,因为在Parent中被定义为public
        System.out.println("Updated id: " + child.id);
    }
}

输出将是:

Previous id: 0
Updated id: 100

对于下一个情况,似乎问题是指实例方法,没有具体说明是否有静态方法。公共的静态方法可以在任何地方调用,并通过修改静态字段创建副作用,还可以访问A实例的私有实例字段,这使得A不是不可变的。

英文:

A could extend a class with fields that are public, in which case, those fields can be modified despite A itself not defining any mutable fields, as it will inherit fields and instance methods from its parent class.

Consider the following code:

class Child extends Parent {
    private String name;
}
class Parent {
    public int id;
}
class TestChild {
    public static void main(final String[] args) {
        final Child child = new Child();
        //String s = child.name;&lt;--The field Child.name is not visible
        System.out.println(&quot;Previous id: &quot; + child.id);
        child.id = 100;//&lt;--We can modify this because it is defined as public in Parent
        System.out.println(&quot;Updated id: &quot; + child.id);
    }
}

The output will be:

Previous id: 0
Updated id: 100

For the next case, it seems that the question meant methods as in instance methods, not specifying whether or not there are static methods. Static methods that are public can be called anywhere and create side effects by modifying static fields and can also access private instance fields on instances of A, which makes A not immutable.

答案2

得分: 1

Point 2:

类 A 的一个实例不是不可变的,因为它继承了一个可以被改变的 bValue 字段。


Point 3:

类 A 的实例可以通过调用静态方法 A.mutate 进行改变,该方法具有完全访问 A 的私有字段的权限。目前的规定中,"在 Java 中,类 A 的所有实例方法都是私有的",不适用于静态方法。

英文:

Point 2:

class B {
    public int bValue;
}

class A extends B {
    private int aValue;
}

An instance of A is not immutable because it has inherited a bValue field that can be changed.


Point 3:

class A {
    private int x;

    public static void mutate(A a) {
        a.x += 1;
    }
}

Instances of A can be mutated by calling the static method A.mutate, which has full access to A's private fields. The stipulation as it now reads, "all instance methods of class A in Java are private", does not apply to static methods.

答案3

得分: 0

以下是您要翻译的内容:

所有之前的答案都是正确的。关于问题> 3. A不一定是不可变的,因为您可以通过静态方法更改其字段

可以通过以下方式实现:

public class Test {
public static void main(String[] args) {
    A a = new A(10);
    System.out.println(a);
    A.mutateObj(20);
    System.out.println(a);
 }
}

class A {
 private static A a;
 private int x;

 A(int x) {
    this.a = this;
    this.x = x;
 }

 public static void mutateObj(int b) {
    a.x = b;
 }

 @Override
 public String toString() {
    return "A{" +
            "x=" + x +
            '}';
 }
}

结果 =>

A{x=10}
A{x=20}
英文:

All the previous answers were right. On the question regarding
> 3. A is not for sure immutable because you might be able to change its fields from static methods

can be achieved like

public class Test {
public static void main(String[] args) {
    A a = new A(10);
    System.out.println(a);
    A.mutateObj(20);
    System.out.println(a);
 }
}

class A {
 private static A a;
 private int x;

 A(int x) {
    this.a = this;
    this.x = x;
 }

 public static void mutateObj(int b) {
    a.x = b;
 }

 @Override
 public String toString() {
    return &quot;A{&quot; +
            &quot;x=&quot; + x +
            &#39;}&#39;;
 }
}

Result =>

A{x=10}
A{x=20}

huangapple
  • 本文由 发表于 2020年7月23日 02:52:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/63041281.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定