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

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

final Myclass obj = new Myclass(); 

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

我想确保一旦构造​​对象本身不会改变。

只是让它不可变(就像String一样)。 或者将其包装在另一个对象中,该对象限制对相关对象的mutator的访问(如Collections.unmodifiableList()和consorts do)。

你混合了两件事:final和immutable。

变量可以是final ,因此在初始化之后你不能改变它的值(或对象引用)(当然你可以改变引用的对象属性)

对象可以是不可变的 (不是关键字而是属性),因此在创建后不能更改它的 。 String是一个很好的例子 – 你不能在String对象中更改后备char []。

你想要的是一个不可变对象 。 Java中没有可以立即使对象不可变的关键字。 您必须设计对象的逻辑,以便无法更改其状态。 正如BalusC所说,你可以将它包装在另一个限制访问其mutator的对象中。

我不认为有任何内置的关键字可以在Java中实现这一点。 即使引用是常量/最终,对象的内部仍然可以更改。

您最好的选择是拥有类的ReadOnly实现版本。

你可以在这里阅读更多相关信息: http : //en.wikipedia.org/wiki/Const-correctness#final_in_Java

在Java中,不可变类通常意味着它没有“setter”,任何可以使用“getter”访问的字段也应该是不可变的。 为了使您的数据能够在类中启动,您需要一个将值作为参数的构造函数:

公共类MyClass {
  字符串;
   int somethingElse;

   //该类只能由构造函数修改
   public MyClass(String something,int somethingElse){
     this.something =某事;
     this.somethingElse = somethingElse;
   }

   //访问“某事”。 请注意,它是一个String,它是不可变的。
   public String getSomething(){
    回报一些东西
   }

   //访问“somethingElse”。 请注意,它是一个int,它是不可变的。
   public int getSomethingElse(){
     返回一些东西;
   }
 }

是的,你似乎忘了设置类型。

 final MyClass obj = new Myclass(); 

这意味着obj只能分配一次。 Java没有像C ++那样的const关键字。 如果MyClass没有被声明为final( 最终类MyClass {…} ),它仍然可以改变。

最终变量应在声明时分配。

 final MyClass obj = new MyClass(); 

在java对象中,常量意味着您无法更改其引用,但您可以更改其状态变量的值,直到它们不是最终的。 如果所有的成员变量都是最终的,那么它就是一个完美的常数,你无法改变任何东西。

这是一种包装任何对象以使其“粗略”不可变的方法。

所有不是’getters’的方法调用都会抛出exception。 此代码将getter定义为满足以下条件的方法:

  • 方法的名称以getis开头
  • 它不需要任何参数
  • 它返回一个值(不是void返回类型)

是的,getter方法可以改变一个对象。 但是,如果你的代码(或你正在使用的代码)正在这样做,你有一些更大的问题,请去帮助:)

代码:

 class ImmutableWrapper public static  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