什么是C ++的const成员函数的Java等价物?

时间:2011-05-04 16:07:41

标签: java

在C ++中,我可以定义一个 accessor 成员函数,该函数返回私有数据成员的值(或引用),这样调用者就无法以任何方式修改该私有数据成员。 / p>

有没有办法在Java中执行此操作?

若然,怎么样?

我知道final关键字但AFAIK,当应用于方法时:

  1. 防止覆盖/多态化 子类中的那个方法。
  2. 使该方法内联。(见@Joachim Sauer的评论)
  3. 但它不会限制方法返回对数据成员的引用,以致调用者无法修改它。

    我忽略了一些显而易见的事情吗?

9 个答案:

答案 0 :(得分:21)

Java中没有等同于C const“类型修饰符”(遗憾的是)。

最接近的是在可变对象周围返回不可变对象或不可变包装。

不变性不是Java的语言特性,因此您将不得不依赖于库。

不可变对象的示例是:

  • 原始包装IntegerCharacter,..
  • String
  • File
  • URL

常用的不可变包装器(即防止突变的可变类型的包装器)是the Collecton.unmodifiable*() methods返回的包装器。

答案 1 :(得分:7)

这在java中不存在。 finalconst具有不同的语义,除非应用于基本类型的变量。 java解决方案通常涉及创建不可变类 - 其中对象在构造中初始化,并且不提供允许更改的访问器。这类的例子可以是例如StringInteger

答案 2 :(得分:5)

您要么返回immutable对象,要么返回私有实例变量的副本。这样,对象的内部状态就会受到“保护”而无法修改,即:

private MyMutableObject mutable = ...

public MyMutableObject getMutableObject() {
   return new MyMutableObject(this.mutable);
}
`

答案 3 :(得分:4)

你没有忽视任何事情。纯Java无法做到这一点。可能有些库使用注释提供了一些子集,但我不知道任何副手。

传递对不可变数据的引用的方式是使您传递的类不可变,简单明了。在一些非常有限但常见的情况下,有一些库函数可以帮助您生成某些数据的不可变视图。这是一个例子:

private List<String> internalData;

public List<String> getSomeList() {
    return Collections.unmodifiableList(internalData);
}

答案 4 :(得分:2)

您可以返回该成员的副本,因此更改不会反映在私有引用所指向的对象中。当然,对于原语,这个问题不存在。

请注意内存使用情况!对于所有情况,这可能不是正确的解决方案。在这种情况下,另一个答案中建议的不可变对象可能是要走的路。

答案 5 :(得分:1)

我认为在Java中没有一种方法可以用于非原始对象(你总是传递对这些对象的引用)。你可以做的最接近的是返回一个对象的副本(使用克隆或类似的东西);但这不是非常惯用的Java。

我想只访问成员对象的“可见”部分,您可以做的是创建一个带有可见部分的界面,然后返回此界面。例如:

public interface Bar {
     public int getBing();
}

public class BarImpl implements Bar {
     private int bing;
     public int getBing() {
        return bing;
     }
     public void setBing(int bing) {
        this.bing = bing;
     }
}

public class Foo {
     private BarImpl bar;

     public Bar getNonModifiableBar() {
         return bar; // Caller won't be able to change the bing value, only read it.
     }
}

答案 6 :(得分:0)

取决于返回的对象以防止修改。 Java不提供对不可修改对象的声明/编译时检查,除非该类型缺少mutator。

JDK中有一些支持:像Collection.unmodifiableCollection这样的方法会创建一个对象,如果客户端调用集合mutator方法,它将抛出运行时异常。

如果您真的很有动力,可以通过定义只能自己公开/实现访问器方法的只读接口(或类)来进行编译时检查。请记住,仅仅声明方法返回只读接口不会阻止运行时修改,如果客户端使用内省并且对象提供了mutators(不抛出UnsupportedOperationException)。

答案 7 :(得分:0)

避免此问题的一种方法是不公开数据结构(另一种方法是返回副本或不可变的包装器)

e.g。而不是

public List<String> getSomeList();

public String getSomeElement(int index);

答案 8 :(得分:0)

当你做这样的事情时:

Object2 obj2 = obj1.getObj2();
obj2 = new Object2();

原始私有成员(obj1.obj2)仍然像以前一样(只是为了确保你掌握了这个概念)。你可以省略setter到obj2,这样就不会改变内部字段。

如果您希望Object2字段不可变,则需要应用相同的模式(私有字段,不设置setter)。

这回答了你的问题?