Final variable manipulation in Java

前端 未结 11 700
无人及你
无人及你 2020-11-28 23:28

Could anyone please tell me what is the meaning of the following line in context of Java:

final variable can still be manipulated unless it\'s immut

相关标签:
11条回答
  • 2020-11-28 23:57

    Yes the final variable can be modified.

        final StringBuffer s = new StringBuffer();
        // won't work
        s = new StringBuffer();
        //this works
        s.append("hai");
    

    You can't change the reference but the fields of the the object can be modified. for more details

    0 讨论(0)
  • 2020-11-28 23:59

    You cannot change what object or value a final variable refers to. You can only assign a final variable once.

    This has no effect on whether you can change the state of the object. The object itself can still be manipulated unless it is coded in such a way that this manipulation is forbidden. An immutable object is an object whose state cannot change.

    0 讨论(0)
  • 2020-11-29 00:05

    As others have said, it means that you can manipulate the object the variable points at, but you cannot change the reference (i.e. assign another object to the variable).

    Objects that are mutable by design, such as a List can be changed (you can add elements to them) whereas if you have an immutable object such as a String or Integer you won't be able to change it (all the operations the class String supports return a new instance, and don't modify the actual object).

    0 讨论(0)
  • 2020-11-29 00:07

    The following is code I created several years back to turn final off and then back on so you can modify the reference/value, it will only work on variables, but it does work.

    You can also do something similar with method handles, however unless you are writing some form of auto object parser/generator, I would avoid doing either like the plague.

    public static void setValueOnField(Object instance, Field field, Object value)
            throws NoSuchFieldException, IOException, IllegalArgumentException,
            IllegalAccessException {
        try (Accessor<Field> access = open(field)) {
            field.set(instance, value);
        }
    }
    
    
      public static class Accessor<T extends AccessibleObject & Member>
                implements Closeable {
            private final boolean isAccessible;
            private final boolean isFinal;
            private final int modifiers;
            private final T accessibleObject;
    
            private Accessor(T accessibleObject) throws IOException {
                super();
                if (accessibleObject == null) {
                    throw new IOException(
                            "Error preparing field for accesibility: Field is null");
                }
                try {
                    this.accessibleObject = accessibleObject;
                    this.modifiers = accessibleObject.getModifiers();
                    this.isAccessible = accessibleObject.isAccessible();
                    this.isFinal = Modifier.isFinal(modifiers);
                    if (!this.isAccessible) {
                        accessibleObject.setAccessible(true);
                    }
                    if (this.isFinal) {
                        getModifiersField(accessibleObject).setInt(
                                accessibleObject, modifiers & ~Modifier.FINAL);
                    }
                } catch (Exception e) {
                    throw new IOException("Error preparing field for accesibility",
                            e);
                }
    
            }
    
            @Override
            public void close() throws IOException {
    
                if (!this.isAccessible) {
                    accessibleObject.setAccessible(false);
                }
                if (this.isFinal) {
                    try {
                        getModifiersField(accessibleObject).setInt(
                                accessibleObject, modifiers);
                    } catch (Exception e) {
                        throw new IOException("Error setting field to final", e);
                    }
                }
            }
    
            public T getAccessibleObject() {
                return accessibleObject;
            }
    
            private static Field getModifiersField(AccessibleObject toFetch) {
                Field field;
                try {
                    field = toFetch.getClass().getField("modifiers");
                    field.setAccessible(true);
                    return field;
                } catch (Exception e) {
                    throw new RuntimeException(
                            "Error occured getting modifiers field", e);
                }
            }
        }
    
    0 讨论(0)
  • 2020-11-29 00:09

    The one that always kills me?

    If you want final variables to actually be as safe as you thought they were, you need a lot of extra code to return a copy of a String[].

    0 讨论(0)
提交回复
热议问题