如何在 Java 中创建常量对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2147122/
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
How do I create a constant object in Java?
提问by gameover
How do I create a reference to a constant object?
如何创建对常量对象的引用?
final Myclass obj = new Myclass();
does not work, it says obj(the reference) should not be re-assigned but we can still change the object referred.
I want to ensure that the object itself does not change once constructed.
不起作用,它说 obj(引用)不应重新分配,但我们仍然可以更改引用的对象。
我想确保对象本身一旦构造就不会改变。
回答by BalusC
Just make it immutable (like Stringis). Or wrap it in another object which restricts access to mutators of the object in question (like Collections.unmodifiableList()and consorts do).
让它不可变(就像String是)。或者将它包装在另一个对象中,该对象限制对相关对象的修改器的访问(就像Collections.unmodifiableList()和配偶一样)。
回答by Andreas Dolk
You are mixing two things: final and immutable.
您正在混合两件事:最终的和不可变的。
A variable can be final, so you can't change it's a value (or object reference) after it is initialized (but of course you can change the reference's objects attributes)
变量可以是final,因此您不能在初始化后更改它的值(或对象引用)(但当然您可以更改引用的对象属性)
An object can be immutable(not a keyword but a property), so you can't change it's valueafter it is created. The string is a good example - you can not change the backing char[] inside a String object.
对象可以是不可变的(不是关键字而是属性),因此您无法在创建后更改其值。字符串就是一个很好的例子——你不能改变 String 对象内的支持 char[]。
回答by Erkan Haspulat
What you want is an Immutable Object. There are no keywords in Java that can instantly make an object immutable. You have to design the object's logic, so that its state cannot be changed. As BalusC put, you can wrap it in another object which restricts access to its mutators.
你想要的是一个Immutable Object。Java 中没有关键字可以立即使对象不可变。您必须设计对象的逻辑,使其状态无法更改。正如 BalusC 所说,您可以将它包装在另一个对象中,该对象限制对其修改器的访问。
回答by dhg
In Java, an immutable class is generally means that it doesn't have "setters" and any field that can be accessed with a "getter" should also be immutable. In order to get your data into the class to start, you'll need to have a constructor that takes the values as arguments:
在 Java 中,不可变类通常意味着它没有“setter”,任何可以用“getter”访问的字段也应该是不可变的。为了让您的数据进入类以启动,您需要有一个将值作为参数的构造函数:
public class MyClass {
String something;
int somethingElse;
// The class can only be modified by the constructor
public MyClass(String something, int somethingElse) {
this.something = something;
this.somethingElse = somethingElse;
}
// Access "something". Note that it is a String, which is immutable.
public String getSomething() {
return something;
}
// Access "somethingElse". Note that it is an int, which is immutable.
public int getSomethingElse() {
return somethingElse;
}
}
回答by rui
I don't think there's any built in keyword to make that possible in Java. Even if the reference is constant/final, the internals of the object could still be changed.
我认为在 Java 中没有任何内置关键字可以实现这一点。即使引用是常量/最终的,对象的内部结构仍然可以改变。
Your best options is to have a ReadOnly implementation version of your class.
您最好的选择是拥有您的类的 ReadOnly 实现版本。
You can read more about this here: http://en.wikipedia.org/wiki/Const-correctness#final_in_Java
您可以在此处阅读更多相关信息:http: //en.wikipedia.org/wiki/Const-correctness#final_in_Java
回答by cobbzilla
Here is a way to wrap any object to make it "roughly" immutable.
这是一种包装任何对象以使其“大致”不可变的方法。
All method calls that are not 'getters' will throw an Exception. This code defines a getter as a method that meets these criteria:
所有不是“getter”的方法调用都会抛出异常。此代码将 getter 定义为满足以下条件的方法:
- name of the method starts with
getoris - it takes no arguments
- it returns a value (not
voidreturn type)
- 方法的名称以
get或开头is - 它不需要参数
- 它返回一个值(不是
void返回类型)
Yes, getter methods couldmutate an object. But if your code (or code you are using) is doing that, you have some bigger problems, please go get some help :)
是的,getter 方法可以改变一个对象。但是如果您的代码(或您正在使用的代码)正在这样做,那么您有一些更大的问题,请寻求帮助:)
the code:
代码:
class ImmutableWrapper
public static <T> T wrap(T thing) {
return (T) Proxy.newProxyInstance(thing.getClass().getClassLoader(), new Class[]{thing.getClass()}, OnlyGettersInvocationHandler.instance);
}
private static class OnlyGettersInvocationHandler implements InvocationHandler {
public static InvocationHandler instance;
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final String name = method.getName();
if ((args == null || args.length == 0)
&& (name.startsWith("get") || name.startsWith("is")
&& !method.getReturnType().equals(Void.class))) {
return method.invoke(proxy, args);
} else {
throw new UnsupportedOperationException("immutable object: " + proxy + ", cannot call " + name);
}
}
}
}
SomeClass myThing = ... create and populate some object ...
SomeClass myImmutableThing = ImmutableWrapper.wrap(myThing);
myImmutableThing.setValue('foo'); // throws Exception
myImmutableThing.whatever(); // throws Exception
myImmutableThing.getSomething(); // returns something
myImmutableThing.isHappy(); // returns something
回答by GuruKulki
In java object constant means you cannot change its reference but you can change the values of its state variables untill they are not final. if all the member variables are final then its a perfect constant, where you cannot change anything.
在 java 对象中,常量意味着你不能改变它的引用,但你可以改变它的状态变量的值,直到它们不是最终的。如果所有成员变量都是最终的,那么它就是一个完美的常量,你不能改变任何东西。
回答by Daff
Yes it does you seem to have forgotten to set the type.
是的,您似乎忘记了设置类型。
final MyClass obj = new Myclass();
That means that obj can only be assigned once. Java does not have a const keyword like C++ does. If MyClass is not declared final (final class MyClass { ... }) it can still change.
这意味着 obj 只能分配一次。Java 没有像 C++ 那样的 const 关键字。如果 MyClass 未声明为 final (final class MyClass { ... }),它仍然可以更改。
回答by artemb
final variables should be assigned in the moment of declaration.
final 变量应该在声明的时候赋值。
final MyClass obj = new MyClass();

