【问题标题】:Returning a reference to a mutable object value stored in one of the object's fields exposes the internal representation of the object返回对存储在对象字段之一中的可变对象值的引用会公开对象的内部表示
【发布时间】:2014-01-06 00:02:05
【问题描述】:

在我的代码中针对以下几行运行 checkstyle 时出现此错误:

@Override
public String[] getDescriptions() {
    return DESCRIPTIONS;
}

但说明 IS NOT 可变。定义为:

private static final String[] DESCRIPTIONS = new String[NUM_COLUMNS];

static {
   // In a loop assign values to the array.
   for (int i = 0; i < NUM_COLUMNS; ++i) {
       DESCRIPTIONS[i] = "Some value";
   }
}

这是完整的错误信息:

"Returning a reference to a mutable object value stored in one 
 of the object's fields exposes the internal representation of
 the object. If instances are accessed by untrusted code, and 
 unchecked changes to the mutable object would compromise security
 or other important properties, you will need to do something 
 different. Returning a new copy of the object is better approach
 in many situations."

相关问题:Link

【问题讨论】:

  • DESCRIPTIONS中的项目是可变的。

标签: java checkstyle mutable internals


【解决方案1】:

数组和一些集合不是不可变的,因为它们的内容仍然是可变的。

Java 中的不变性只涉及对象的引用分配,而不涉及其深层内容。

试试这个:

@Override
public String[] getDescriptions() {
    return Arrays.copyOf(DESCRIPTIONS, DESCRIPTIONS.length);
}

顺便说一句,注意 java 命名约定..:descriptions,而不是 DESCRIPTIONS

【讨论】:

  • @Sotirios Delimanolis 是的,不可修改的集合不应该担心这种可变性。
  • 这是我的团队遵循的命名约定(非常严格)。感谢您的快速解释和可能的解决方案。
  • @user1071840 非常奇怪的约定;)不客气。
  • 我相信约定是正确的:DESCRIPTIONS 是一个 static final String[] 我认为他们的目标是使其成为一个常量
  • @Adrian Shum 用大写字母(甚至是final)改变变量(在本例中为数组)的概念会让我感到困惑。以下答案解释了原因,我完全同意:stackoverflow.com/a/18641425/985949
【解决方案2】:

引用变量是final,因此您不能将另一个数组分配给DESCRIPTIONS。但是,对象本身是可变的(数组总是可变的),final 与否。如果您返回引用,那么您将失去对变量内容的控制,从而违反封装。

您需要返回数组的副本,或者根本不返回数组,而是提供一种方法来获取数组的特定元素,如果这足够好的话。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多