Java How to access data from local inner class - java

Below code is some example analogous to what I am trying to achieve. I have to store the data from internal class but the compiler complains following:
returnedValue=(MyXYZClass)value.toString();
Local variable selectedBusinessArea defined in an enclosing scope must be final or effectively final
private String methodInMainClass(Object someRef){
String returnedValue="";
new SomeInnerClass(Object someRef){
#Override
public String getData(Object value){
if(value instanceof MyXYZClass){
returnedValue=(MyXYZClass)value.toString(); // Not Happening. I cannot assign it to the outer variable.
}
return super.getData(value);
}
}
How can I store the value from the overriden method in internal class?

The local variable in your code sample is returnedValue. It has to be final or effectively final but it's neither declared final nor effectively final since it gets a value assigned.
How to solve this:
All you need is final or effectively final variable which can store the state of returnedValue. There are many ways to do it.
One way would be to define a class like BoxedValue.
public class BoxedValue<T> {
private T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
}
Using it in the code:
private String methodInMainClass(Object someRef){
BoxedValue<String> returnedValue = new BoxedValue<>("");
new SomeInnerClass(Object someRef){
#Override
public String getData(Object value){
if(value instanceof MyXYZClass){
returnedValue.set((MyXYZClass)value.toString()); // Not Happening. I cannot assign it to the outer variable.
}
return super.getData(value);
}
}
return returnedValue.get();
}
The variable returnedValue is now effectively final.
If you don't want to define an additional class, you can use any other to store the state, i.e. Optional<String> returnedValue = Optional.of("").

You can use an array in order to do the trick
private String methodInMainClass(Object someRef){
String[] returnedValue= {""};
new SomeInnerClass(someRef){
#Override
public String getData(Object value){
if(value instanceof MyXYZClass){
returnedValue[0] = ((MyXYZClass)value).toString(); // Not Happening. I cannot assign it to the outer variable.
}
return super.getData(value);
}
}
// [...]

it is not about inner class this also happened in lambda, the you can not change value of var from out of scope of lambda or inner class, otherwise you may make access issue and for multithread race condition, as workaround you may use one of Atomic family classes for that like AtomicReference<T> or AtomicInteger for ex. :
AtomicInteger count = new AtomicInteger(0);
Runnable r = () -> {
count.getAndIncrement();
};
r.run();
System.out.println(count);
Note here that I used only main thread not created new one to not face race condition.

Related

Is the safe publishing of final instance-variables transitive for non-final secondary references?

I know that final instance-variables are published safely to all threads, after the constructor is finished. However, I wonder whether this is still safe, if the final instance-variable contains a reference to an object that contains a non-final instance-variable. This secondary, non-final instance-variable is never changed after the constructor is done. Consider the following example:
public class NonFinalImmutable {
private Iterable<String> list = Collections.unmodifiableList(Arrays
.asList("foo", "bar", "foobar"));
public Iterable<String> getList() {
return list;
}
}
public class FinalImmutable {
private final NonFinalImmutable reference;
private final String[] array;
public FinalImmutable(NonFinalImmutable reference,
String... arrayEntries) {
this.reference = reference;
this.array = arrayEntries;
}
public NonFinalImmutable getReference() {
return reference;
}
public String[] getArray() {
return array;
}
}
private void execute() {
new Thread() {
#Override
public void run() {
useLater(construct());
}
}.start();
}
private FinalImmutable construct() {
return new FinalImmutable(new NonFinalImmutable(), "asdf", "jklö");
}
private void useLater(FinalImmutable finalImmutable) {
new Thread() {
#Override
public void run() {
for (String s : finalImmutable.getReference().getList()) {
System.out.println(s);
}
System.out.println();
for (String s : finalImmutable.getArray()) {
System.out.println(s);
}
}
}.start();
}
Is it safe to use the contents of the instance-variables FinalImmutable.reference and FinalImmutable.array in another thread even though they contain non-final instance-variables?
Yes, there is a freeze-action which occurs when assigning final fields. You should read Aleksey Shipilëv's blog it's really useful. He discusses the freeze action semantics in a 2014 blog entry
And here is how it is formally specified. Notice that w may not be the write of final field, and r2 is not the read of the final field. What really matters is that the subchain containing freeze action F, some action a, and r1 which reads the final field — all together make r2 observe w.
Notice two new orders, dereference order, and memory
In the blog he proves that a write of final field happens before some action which in turn happens before a subsequent non-final field read r2.
Also in your example, since you first construct the a non-shared NonFinalImmutable the final assignment should freeze the writes occurred prior. If the NonFinalImmutable was accessible outside, all bets are off.

Declare final variable, but set later

I know this is fairly simple topic, but I really want to wrap my head around it.
This is what I'm trying to do, but it doesn't like the final modifier. Is there another way to achieve the effect I'm looking for? Which is basically that I want to make sure the id can not change durning the Activities entire life.
private final long mId;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mId = getIntent().getLongExtra(ID_KEY, -1);
}
I should point out that this is Android code. Thanks for all the help. I'm not worried about getters or setters or anyone changing my code. The reason I asked was to future proof my code for the next developer to take over. I found this post that also helps shed some light. Android - Activity Constructor vs onCreate
You can set a final variable only in a constructor or in an initializer. Regular methods cannot change the value of variables declared final.
You can't. But you can guarantee no external object changes it if it's private and you don't have a setter for it.
Alternatively, you can wrap the long value in another class - LazyImmutableLong. But this is a more verbose approach, and you probably don't need it (note: the class below is not thread-safe)
class LazyImmutableLong {
private Long value;
public void setValue(long value) {
if (this.value != null) {
return; // the value has already been set
}
this.value = value;
}
public long getValue() {return value;}
}
And in your activity
private LazyImmutableLong id = new LazyImmutableLong();
public void onCreate(..) {
id.setValue(..);
}
The following Worm (Write-Once-Read-Many) class could help in this kind of scenario.
We could create a nested Wrapper class, that stores the final variable you need. To initialize this variable, you just should call a constructor of the wrapper object. When you call the method getData(), you will get a reference of the final variable in case it is initialized, otherwise, you will get null.
The methods getData() and setData(T data) are required to be thread-safe. To provide it, we use a volatile modifier for the wrapper object. Reading a volatile variable is synchronized and writing to a volatile variable is synchronized, too. Even though some efforts were made to make this code thread-safe I didn't test it in this respect. Depending on the level of thread safety you may consider to make setter and getter synchronized.
public class Worm<T> {
private volatile Wrapper<T> wrapper;
public Worm() {}
public Worm(T data) throws IllegalAccessError
{
setData(data);
}
public T getData()
{
if (wrapper == null)
return null;
return wrapper.data;
}
public void setData(T data) throws IllegalAccessError
{
if (wrapper != null)
throw new IllegalAccessError();
else
wrapper = this.new Wrapper<>(data);
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Worm<T> other = (Worm<T>) obj;
return Objects.equals(this.getData(), other.getData());
}
#Override
public int hashCode() {
return Objects.hashCode(this.getData());
}
final private class Wrapper<T> {
final private T data;
Wrapper(T data) {
this.data = data;
}
}
}
private final long mId;
final reference cann't be modified at runtime as per java spec. So, once you declared it as final, mId can't point to something else throughout its lifetime (Unless you use reflection (or) wrap the value in object and modify it through other reference).
You can set later a global final Variable only in your constructor. Example:
public class ClassA {
private final long mID;
public ClassA(final long mID) {
this.mID = mID;
}
}
In this case in each constructor you have to initialize the final variable.
you have to initialize the constructor as soon as you create it, or you could initialize it at the max, in the constructor. Not later than that..
NO it can not be done
if you can declare final at one place and initialize it later, Then What is the mean of final.
If you want to have a constant ID, why don't you use Shared Preferences , store it in SP and retrieve whenever want.

The pattern of final array instead of non-final variable for boolean flag in inner class

I often have a situation in my Java code when I need to set a boolean flag inside an inner class. It is not possible to use primitive boolean type for that, because inner class could only work with final variables from outside, so I use pattern like this:
// class from gnu.trove is not of big importance, just to have an example
private final TIntIntHashMap team = new TIntIntHashMap();
// ....... code ............
final boolean[] flag = new boolean[]{false};
team.forEachValue(new TIntProcedure() {
#Override
public boolean execute(int score) {
if(score >= VICTORY_SCORE) {
flag[0] = true;
}
return true; // to continue iteration over hash map values
}
});
// ....... code ..............
The pattern of final array instead of non-final variable works well, except it is not look beautiful enough to me. Does someone know better pattern in Java ?
Use AtomicBoolean.
Here's a popular StackOverflow question about this issue: Why are only final variables accessible in anonymous class?
How about having a generic holder class which holds object of any type. In your case, it can hold a Boolean type. Something like:
class Holder<T> {
private T genericObj;
public Holder(T genericObj) {
this.genericObj = genericObj;
}
public T getGenericObj() {
return genericObj;
}
public void setGenericObj(T genericObj) {
this.genericObj = genericObj;
}
}
And use it as:
public class Test {
public static void main(String[] args) throws Exception {
final Holder<Boolean> boolHolder = new Holder<Boolean>(Boolean.TRUE);
new Runnable() {
#Override
public void run() {
boolHolder.setGenericObj(Boolean.FALSE);
}
};
}
}
Of course, this has the usual problems that occur with mutable objects that are shared across threads but you get the idea. Plus for applications where memory requirements are tight, this might get crossed off when doing optimizations in case you have a lot of invocations of such methods. Also, using AtomicReference to swap/set references should take care of use from multiple threads though using it across threads would still be a bit questionable.
There are situations where this is the best pattern.
The only improvement I can suggest is return false when you have found a match.
One problem is that the TIntIntHashMap does not have a fold/reduce method so you have to simulate it using foreach. You could try to write your own class extending TIntIntHashMap adding a reduce method.
Other solution is to just extend TIntProcedure to have a value. Something like:
abstract class TIntProcedureWithValue<T> implements TIntProcedure {
private T accumulator;
public T getValue() {return accumulator;}
}
Then you can pass an instance of this class to foreach, set the internal accumulator instead of the external flag array, and get the resulting value afterwards.
I am not familiar with gnu.trove, but generally it's better for the "algortihm" function to be more specific, leaving less code here.
private final IntIntHashMap team = new IntIntHashMap();
boolean found = team.value().containsMatch(new IntPredicate() {
public boolean is(int score) {
return score >= VICTORY_SCORE;
}
});
(More concise syntax should be available in Java SE 8.)
maybe something like that? (implements or extends... I don't know what is TIntProcedure, unfortunately) :
class FlagResult implements TIntProcedure {
boolean flag = false;
#Override
public boolean execute(int score) {
flag = score >= VICTORY_SCORE;
return !flag;
}
};
FlagResult result = new FlagResult();
team.forEachValue(result);
boolean flag = result.flag;

How to avoid inner classes returning values via a single element array?

I've needed to get a value back from an anonymous inner class. Inner classes can only close over final variables, of course, which leads to this horrible workaround:
public String sampleMethod(){
final String[] output = new String[1];
findResult(new SampleOperation(){
#Override
private void perform(){
output[0] = "result";
}
});
return output[0];
}
private void findResult(SampleOperation op){
op.perform();
}
private static interface SampleOperation {
void perform();
}
Obviously a simplified example; here the class is easily removable, but the principal of the problem is there. If there is a dependency further down (inside findResult(), such as a latch that needs triggered) then unwrapping such a class becomes impractical.
Wrapping the final array means it's accessible, but this has one of the worst smells I've ever come across.
Is there a sane way to get a return type from such a delegate? (i.e. Not use this?)
The problem here is that SampleOperation.perform returns void. Just make it return String (or be generic) and it's fine:
public String sampleMethod(){
return findResult(new SampleOperation(){
#Override
private String perform() {
return "result";
}
});
}
private String findResult(SampleOperation op){
return op.perform();
}
private static interface SampleOperation {
String perform();
}
Ultimately, whenever you're thinking about "I need to get a value back" you should be thinking about a value being returned from a method.
Better pattern for this is using callback interface:
final ResultSender<String> sender = ...;
findResult(new SampleOperation(){
#Override
private void perform(){
sender.send("result");
}
});
The variable sender is still final here, but at least the pattern is reusable and you do not have to create array based work-around.

Static blocks and Field.get(null) with static not primitive data fields

I have the following classes:
public class A {
static {
B.load(A.class);
}
public static final C field1 = new C("key1", "value1");
public static final C field2 = new C("key2", "value2");
public static void main(String[] args) {
System.out.println(A.field1);
}
}
and
public class B {
public static void load(Class<?> clazz) {
for (Field field : clazz.getFields()) {
try {
System.out.println("B.load -> field is " + field.get(null));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
and
public class C {
private final String key;
private final String value;
public C(String key, String value) {
super();
this.key = key;
this.value = value;
}
public String getKey() {
return this.key;
}
public String getValue() {
return this.value;
}
#Override
public String toString() {
return "C [key=" + this.key + ", value=" + this.value + "]";
}
}
When A is executed I get:
B.load -> field is null
B.load -> field is null
C [key=key1, value=value1]
Why does field.get(null) return a null value when it is executed? I get no exception and it seems that this behavior is not explained by the Javadoc.
I believe all static members will be executed (for static blocks) and initialized (for static fields) in declaration order. Try placing the static block of class A at the end of the class, or at least after the static fields. Lemme know if that makes a difference.
EDIT: info regarding the behaviour for primitives and Strings...
When you have a final static field that is a primitive or a String literal (or an expression that can be statically evaluated that results in one of these), it's considered a compile-time constant. Basically, setting such a value does not require "computation", like invoking a constructor or evaluating vis-a-vis other fields that may not have been initialized yet. Although Strings aren't primitives, they're given a special treatment in compilation to make String literals in code a possibility.
This means such fields can be assigned as soon as a class has been loaded and is ready for initialization. Although I don't know the specification details regarding that, experimenting with reflection shows that this is what must be happening.
Following sections of the Java language specification are relevant to understanding this behaviour:
Restrictions on the use of fields during initialization. Reflection lets you get to these fields "sooner" than they appear in source code order. If you tried using them directly in a static block that appears before the field declaration you'd get an error regarding an illegal forward reference from the compiler.
Initialization of classes and interfaces.
What constitutes a constant expression.
Final variables. That last paragraph of this section is quite relevant and implies more than its vagueness lets on.
In your class A you have to declare the static fields before the call to your static function.
public static final C field1 = new C("key1", "value1");
public static final C field2 = new C("key2", "value2");
static {
B.load(A.class);
}
The Java tutorial explains it:
A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.

Categories

Resources