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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5886439/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 13:17:09  来源:igfitidea点击:

What is the Java equivalent of C++'s const member function?

java

提问by ef2011

In C++, I can define an accessormember function that returns the value of (or reference to) a private data member, such that the caller cannot modify that private data member in any way.

在 C++ 中,我可以定义一个访问器成员函数,该函数返回(或引用)私有数据成员的值,这样调用者就不能以任何方式修改该私有数据成员。

Is there a way to do this in Java?

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

If so, how?

如果是这样,如何?

I know about the finalkeyword but AFAIK, when applied to a methodit:

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

  1. Prevents overriding/polymorphing that method in a subclass.
  2. Makes that method inline-able.(see comment by @Joachim Sauer below)
  1. 防止在子类中覆盖/多态该方法。
  2. 使该方法可内联。(见下面@Joachim Sauer 的评论)

But it doesn't restrict the method from returning a reference to a data member so that it can't modified by the caller.

但它不限制方法返回对数据成员的引用,因此调用者不能修改它。

Have I overlooked something obvious?

我是否忽略了一些明显的东西?

采纳答案by Lefteris Laskaridis

You either return an immutableobject, or return a copy of the private instance variable. This way, the object's internal state is "protected" from modification, i.e.:

您要么返回一个不可变对象,要么返回私有实例变量的副本。这样,对象的内部状态就被“保护”了不被修改,即:

private MyMutableObject mutable = ...

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

回答by Joachim Sauer

There's no equivalent to the C const"type modifier" in Java (sadly).

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

The closest you can get is to return an immutable object or an immutable wrapper around a mutable object.

你能得到的最接近的是返回一个不可变对象或一个可变对象周围的不可变包装器。

Immutability is not a language feature of Java, however, so you'll have to rely on Libraries.

然而,不变性不是 Java 的语言特性,因此您必须依赖库。

Examples of immutable objects are:

不可变对象的例子有:

  • the primitive wrappers Integer, Character, ..
  • String
  • File
  • URL
  • 原始包装器Integer, Character, ..
  • String
  • File
  • URL

Commonly used immutable wrapper (i.e. wrappers around mutable types that prevent mutation) are those returned by the Collecton.unmodifiable*()methods.

常用的不可变的包装(大约可变类型,以防止突变即包装)是那些通过返回Collecton.unmodifiable*()方法

回答by Erik

This does not exist in java. finaland consthave different semantics, except when applied to a variable of a primitive type. The java solution typically involves creating immutable classes - where objects are initialized in construction and provide no accessors allowing change. Example of such classes would be e.g. Stringor Integer.

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

回答by Mark Peters

You haven't overlooked anything. There is no way in pure Java to do so. There might be libraries which provide some subset of this using annotations, but I don't know any offhand.

你没有忽视任何事情。在纯 Java 中没有办法这样做。可能有一些库使用注释提供了这个的一些子集,但我不知道任何临时的。

The way you pass back a reference to immutable data is to make the class you pass back immutable, plain and simple. There are a couple of library functions to help you produce an immutable viewof some data in some very limited but common cases. Here's one example:

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

private List<String> internalData;

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

回答by no.good.at.coding

You could return a copy of the member, thus changes will not be reflected in the object the private reference points to. With primitives, of course, this problem doesn't exist.

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

Be mindful of memory usage, however! This might not be the right solution for all situations. In that case, an immutable object as suggested in another answer might be the way to go.

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

回答by phtrivier

I don't think there is a way to that in Java for non primitive objects (you're always passing around references to such objects). The closest you could do would be to return a copy of the object (using clone or something like that) ; but that would not be very idiomatic Java.

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

I you want to give access only to the 'visible' part of a member object, what you could do is create an interface with the visible part, and return this interface. For example :

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

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.
     }
}

回答by John

It's up to the returned object to prevent modification. Java doesn't provide declarative/compile-time checking of unmodifiable objects except to the extent that the type lacks mutators.

由返回的对象来防止修改。Java 不提供对不可修改对象的声明性/编译时检查,除非该类型缺少修改器。

There is some support in the JDK: methods like Collection.unmodifiableCollectionwill create an object that will throw runtime exceptions if the client calls collection mutator methods.

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

If you're truly motivated, you can get compile-time checks by defining read-only interfaces (or classes) that only expose/implement accessor methods on your own. Keep in mind that merely declaring that a method returns a read-only interface will not prevent runtime modification if the client uses introspection and the object provides mutators (that don't throw UnsupportedOperationException).

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

回答by Peter Lawrey

One way to avoid this issue is to no expose the data structure (another is returning a copy, or an immutable wrapper)

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

e.g. instead of

例如代替

public List<String> getSomeList();

have

public String getSomeElement(int index);

回答by Anthony Accioly

When you do something like this:

当你做这样的事情时:

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

The original private member (obj1.obj2) remains as it were before (just to be sure that you grasped that concept). You can just omit the setter to obj2 so that the inner field cannot de changed.

原始私有成员 (obj1.obj2) 保持原样(只是为了确保您掌握了该概念)。你可以省略 obj2 的设置器,这样内部字段就不会改变。

If you want Object2 fields to be immutable you will need to apply the same pattern (private fields, no setters).

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

This answer your question?

这回答了你的问题?