Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a better reference container than a one-element array?

Tags:

java

A Java anonymous class can only access a variable from the surrounding method if that variable is final, and hence the inner class can't write to that variable. In order to capture an object created by an enclosed type, I've created a final single-element array to act as a reference:

    final String[] ref = new String[1];
    final Runnable runnable = new Runnable() {
        public void run() {
            ref[0] = "Hello world";
        }
    };

    runnable.run();
    System.out.println(ref[0]);

This appears to work, and I imagine has good performance. But it feels slightly hacky.

Obviously it is trivial to write a Ref class to replace this such that:

    final Ref<String> ref = new Ref<>();
    final Runnable runnable = new Runnable() {
        public void run() {
            ref.set("Hello world");
        }
    };

    runnable.run();
    System.out.println(ref.get());

... is there an existing class in the standard Java runtime that does this?

I've looked at java.lang.ref.Reference, and this isn't the same thing. These are immutable, the only implementations are for weak/phantom references.

like image 476
slim Avatar asked Oct 30 '15 14:10

slim


2 Answers

There's AtomicReference<T> which is what I'd normally use.

final AtomicReference<String> ref = new AtomicReference<String>();
final Runnable runnable = new Runnable() {
    public void run() {
        ref.set("Hello world");
    }
};

runnable.run();
System.out.println(ref.get());

The only downside here is that unless multiple threads are involved, it's slightly misleading as AtomicReference is usually designed for concurrent access - but as a simple wrapper object, I think it's a nice solution.

like image 177
Jon Skeet Avatar answered Nov 15 '22 17:11

Jon Skeet


Your approach is quite common I think for that specific type of situation.

There is also AtomicReference although it is generally used in a multi-threading context.

Or you could use a Callable<String> that returns "Hello World" instead of a Runnable.

like image 20
assylias Avatar answered Nov 15 '22 17:11

assylias