如何创建对常量对象的引用?
final Myclass obj = new Myclass();
不起作用,它表示不应重新分配obj(引用),但我们仍然可以更改引用的对象。
我想确保物体本身在构造后不会改变。
答案 0 :(得分:16)
让它变得不可变(就像String
一样)。或者将它包装在另一个对象中,该对象限制对相关对象的mutator的访问(如Collections.unmodifiableList()
和consorts do)。
答案 1 :(得分:10)
你混合了两件事:最终和不可变。
变量可以是 final ,因此在初始化之后你不能将它改为值(或对象引用)(当然你可以改变引用的对象属性)
对象可以是不可变(不是关键字而是属性),因此在创建后无法更改值。该字符串是一个很好的示例 - 您无法更改String对象中的支持char []。
答案 2 :(得分:9)
你想要的是Immutable Object。 Java中没有可以立即使对象不可变的关键字。您必须设计对象的逻辑,以便无法更改其状态。正如BalusC所说,你可以把它包装在另一个限制访问其mutator的对象中。
答案 3 :(得分:1)
我认为没有任何内置关键字可以在Java中实现这一点。即使引用是常量/最终,对象的内部仍然可以更改。
您最好的选择是拥有类的ReadOnly实现版本。
您可以在此处详细了解:http://en.wikipedia.org/wiki/Const-correctness#final_in_Java
答案 4 :(得分:1)
在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; } }
答案 5 :(得分:0)
是的,您似乎忘记了设置类型。
final MyClass obj = new Myclass();
这意味着obj只能分配一次。 Java没有像C ++那样的const关键字。如果MyClass未被声明为final( final class MyClass {...} ),它仍然可以更改。
答案 6 :(得分:0)
最终变量应在声明时分配。
final MyClass obj = new MyClass();
答案 7 :(得分:0)
在java对象常量中意味着您无法更改其引用,但您可以更改其状态变量的值,直到它们不是最终的。如果所有成员变量都是最终的,那么它就是一个完美的常数,你不能改变任何东西。
答案 8 :(得分:0)
这是一种包装任何对象以使其“粗略”不可变的方法。
所有不是'getters'的方法调用都会抛出异常。此代码将getter定义为满足以下条件的方法:
get
或is
void
返回类型)是的,getter方法可以改变一个对象。但是,如果您的代码(或您正在使用的代码)正在执行此操作,那么您会遇到一些更大的问题,请寻求帮助:)
代码:
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
答案 9 :(得分:0)
也许您可以创建具有最终属性的类。因此,您无法更改它:object == const。
至少有“ String”是不可变的,因为它:
public final class String implements Serializable, Comparable<String>, CharSequence {
private final char[] value;
//...
}