Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does reflection and immutability supposed to work together

According to JSR-133 immutable objects are thread safe and don't need synchronization. However it's possible to update values of final fields using reflection:

package com.stackoverflow;

import java.lang.reflect.Field;

public class WhatsGoingOn {

    static class Immutable {
        private final int value;

        public Immutable(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }

    public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        final Immutable immutable = new Immutable(Integer.MIN_VALUE);

        final Field f = Immutable.class.getDeclaredField("value");
        f.setAccessible(true);

        System.out.println(immutable.getValue());
        f.set(immutable, Integer.MAX_VALUE);
        System.out.println(immutable.getValue());
    }
}

Given number of frameworks (Spring and Hibernate are only a few) which rely on reflection I'm curious what does spec says about this scenario. E.g. if I put field update into synchronized block will that guarantee visibility in other threads, or value will be cached in registers as per spec for final.

http://download.oracle.com/otndocs/jcp/memory_model-1.0-pfd-spec-oth-JSpec/

like image 753
Petro Semeniuk Avatar asked Apr 05 '13 10:04

Petro Semeniuk


People also ask

What is the benefit of immutability?

Immutable objects offer a number of advantages for building reliable applications. As we don't need to write defensive or protective code to keep application state consistent, our code can be simpler, more concise, and less error-prone than when we define mutable objects.

What is immutability and why is it important?

Immutability is the idea that data or objects should not be modified after they are created. This concept has permeated throughout computing, and it is a core tenant of functional programming languages such as Haskell, Erlang, and Clojure.

How does immutability work?

An immutable object (unchangeable object) is an object whose state cannot be modified after it is created. This is in contrast to a mutable object (changeable object), which can be modified after it is created.


2 Answers

An object is considered immutable if its state cannot change after it is constructed. http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html

You are using that Object as mutable since you are changing its state.

It is true that the use of Reflection breaks immutability as defined in the tutorial, since you can use it to change non-constant final fields.

An example of a Reflection-resistant immutable object would be the following:

static class Immutable {
    // This field is a constant, and cannot be changed using Reflection
    private final int value = Integer.MIN_VALUE;

    public int getValue() {
        return value;
    }
}

public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
    final Immutable immutable = new Immutable();

    final Field f = Immutable.class.getDeclaredField("value");
    f.setAccessible(true);

    System.out.println(immutable.getValue());
    f.set(immutable, Integer.MAX_VALUE);
    System.out.println(immutable.getValue());
}

In this instance your reflection test will fail, and the value will remain Integer.MIN_VALUE. But hey, we could always use native code or a memory editor to change that value to something else.

If you go this far into hacking with reflection, you might as well not call your field final and provide methods for manipulating it.

like image 115
Ben Barkay Avatar answered Sep 18 '22 08:09

Ben Barkay


All bets are off with reflection if you insist on switching access control off and doing naughty things.

Static constants are usually inlined at compile time so changing their value probably would have no impact anyway. The result really depends on how clever the optimiser is when compiling, and how clever the JIT compiler is at run time.

End result: "Here be dragons, fear all who dare to tread here!"

like image 31
Chris Cooper Avatar answered Sep 22 '22 08:09

Chris Cooper