简体   繁体   中英

How do I create a constant object in Java?

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.

Just make it immutable (like String is). Or wrap it in another object which restricts access to mutators of the object in question (like Collections.unmodifiableList() and consorts do).

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)

An object can be immutable (not a keyword but a property), so you can't change it's value after it is created. The string is a good example - you can not change the backing char[] inside a String object.

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.

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.

Your best options is to have a ReadOnly implementation version of your class.

You can read more about this here: http://en.wikipedia.org/wiki/Const-correctness#final_in_Java

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:

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

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.

final 变量应该在声明的时候赋值。

final MyClass obj = new MyClass();

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.

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:

  • name of the method starts with get or is
  • it takes no arguments
  • it returns a value (not void return type)

Yes, getter methods could mutate an object. But if your code (or code you are using) is doing that, you have some bigger problems, please go get some help :)

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

Mayby you can create class with final attributes. So, you can't change it: object == const.

At least "String" immutable because of it:

public final class String implements Serializable, Comparable<String>, CharSequence {
    private final char[] value; 
//...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM