Reputation: 1963
I'll just paste the code then explain what I need. I'm lost as to how to acheive this, and I can't even think of alternatives that fit my code very well.
public Transform findById(final int id) {
final Transform returnTransform = null;
execute(new IExecutor() {
Transform returnTransform = null;
@Override
public boolean execute(Transform transform) {
if (transform.getID() == id) {
returnTransform = transform;
return true;
}
return false;
}
});
return <returnTransform>;
}
What I need, is get the variable 'returnTransform' from inside the interface and use it to return from the 'findById' method.
I can't define a variable in the method, because it has to be final to access within the method: and I need to change it.
One solution would be to define the 'returnTransform' variable directly in the class, but it seems tacky. Any other genius ideas from anyone?
Thanks :)
Upvotes: 1
Views: 393
Reputation: 62864
You can create a local class, that wraps the Transform
variable and exposes accessor methods for it. Then you can use a final
wrapper instance and you will be allowed to change its internal state.
For example:
public Transform findById(final int id) {
class Wrapper {
private Transform returnTransform = null;
Transform getReturnTransorm() { return returnTransform; }
void setReturnTransform(Transform returnTransform) {
this.returnTransform = returnTransform;
}
}
final Wrapper wrapper = new Wrapper();
execute(new IExecutor() {
@Override
public boolean execute(Transform transform) {
if (transform.getID() == id) {
wrapper.setReturnTransform(transform);
return true;
}
return false;
}
});
return wrapper.getReturnTransform();
}
Upvotes: 1
Reputation: 7461
You may define your own interface, which would have method to return returnTransform
, something like:
public interface ExecutorWithTransform extends IExecutor {
public Transform getTransform();
}
Then you should use this interface in code, when creating instance:
ExecutorWithTransform executor = new ExecutorWithTransform() {
Transform returnTransform = null;
public Transform getTransform() {
return returnTransform;
}
@Override
public boolean execute(Transform transform) {
if (transform.getID() == id) {
returnTransform = transform;
return true;
}
return false;
}
};
execute(executor);
return executor.getTransform();
Also, there's a workaround, which will allow you using non-final variables inside the anonymous interface. You should just wrap your varible with some variable holder, for example, AtomicReference
:
final AtomicReference<Transform> returnTransform = new AtomicReference<>();
execute(new IExecutor() {
@Override
public boolean execute(Transform transform) {
if (transform.getID() == id) {
returnTransform.set(transform);
return true;
}
return false;
}
});
return returnTransform.get();
But this is not supposed to be idiomatic way.
Upvotes: 3
Reputation: 18143
Create a class implementing IExecutor
which contains a field of type Transform
with getter and which sets it in execute
- then you can pass an object of this class to execute
and getTransform
afterwards.
Upvotes: 0