如何在Java中创建常量对象?

时间:2010-01-27 13:28:13

标签: java

如何创建对常量对象的引用?

final Myclass obj = new Myclass();

不起作用,它表示不应重新分配obj(引用),但我们仍然可以更改引用的对象。

我想确保物体本身在构造后不会改变。

10 个答案:

答案 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定义为满足以下条件的方法:

  • 方法的名称以getis
  • 开头
  • 不需要参数
  • 它返回一个值(不是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; 
//...
}