Related
Is it possible to access an object created in one class from another class without using parameters/arguments?
For example:
public class Main {
public static void main(String[] args) {
Two make = new Two(); // Object I created.
make.ham();
}
}
class Two {
public void ham() {
System.out.println("Ham.");
}
}
class Three {
public static void accessObject() {
// Can I access the object make here without parameters?
}
}
What I understood is that you want to access to make object, created inside Main class (Two make = new Two());. And yes, it's possible to do it.
You have to create your variable make as global and static (and it's recommended be public or protected, in case you have your classes in separate files).
So, inside your Main class, you will have to do something like:
public class Main {
public static Two make;
public static void main(String[] args) {
make = new Two(); // Object I created.
make.ham();
Three.accessObject();
}
}
As you can see, I created the make variable as static and global. This is necessary because your main method is static, and it's global to be able to be recognized by other classes. And to can call to accessObject method, I did it with the class name (because that method is static)(Three.accessObject();)
And finally inside your Three class, in the accessObject method it's necessary call to the static variable make from Main class:
class Three {
public static void accessObject() {
System.out.println("using make object from Main class in Three class...");
Main.make.ham();
}
}
As you can see now, I called the variable make with the name class Main because it's static, and finally, you will be able to call the ham method by this way.
You could you inheritance to solve your problem. For example, you would write:
class Three extends Two {
public static void accessObject() {
// You can now access the "Two" object since you have now made
// Three a subclass of Two.
}
}
EDIT:
If you wanted to say, change the implementation of the ham() method, you could do something like this:
class Two {
public void ham() {
System.out.println("Ham.");
}
}
class Three extends Two {
#Override
public void ham() {
System.out.println("I'm inside ham, but inside the Three class.);
}
}
We can put code in a constructor or a method or an initialization block. What is the use of initialization block? Is it necessary that every java program must have it?
First of all, there are two types of initialization blocks:
instance initialization blocks, and
static initialization blocks.
This code should illustrate the use of them and in which order they are executed:
public class Test {
static int staticVariable;
int nonStaticVariable;
// Static initialization block:
// Runs once (when the class is initialized)
static {
System.out.println("Static initalization.");
staticVariable = 5;
}
// Instance initialization block:
// Runs each time you instantiate an object
{
System.out.println("Instance initialization.");
nonStaticVariable = 7;
}
public Test() {
System.out.println("Constructor.");
}
public static void main(String[] args) {
new Test();
new Test();
}
}
Prints:
Static initalization.
Instance initialization.
Constructor.
Instance initialization.
Constructor.
Instance initialization blocks are useful if you want to have some code run regardless of which constructor is used or if you want to do some instance initialization for anonymous classes.
would like to add to #aioobe's answer
Order of execution:
static initialization blocks of super classes
static initialization blocks of the class
instance initialization blocks of super classes
constructors of super classes
instance initialization blocks of the class
constructor of the class.
A couple of additional points to keep in mind (point 1 is reiteration of #aioobe's answer):
The code in static initialization block will be executed at class load time (and yes, that means only once per class load), before any instances of the class are constructed and before any static methods are called.
The instance initialization block is actually copied by the Java compiler into every constructor the class has. So every time the code in instance initialization block is executed exactly before the code in constructor.
nice answer by aioobe
adding few more points
public class StaticTest extends parent {
static {
System.out.println("inside satic block");
}
StaticTest() {
System.out.println("inside constructor of child");
}
{
System.out.println("inside initialization block");
}
public static void main(String[] args) {
new StaticTest();
new StaticTest();
System.out.println("inside main");
}
}
class parent {
static {
System.out.println("inside parent Static block");
}
{
System.out.println("inside parent initialisation block");
}
parent() {
System.out.println("inside parent constructor");
}
}
this gives
inside parent Static block
inside satic block
inside parent initialisation block
inside parent constructor
inside initialization block
inside constructor of child
inside parent initialisation block
inside parent constructor
inside initialization block
inside constructor of child
inside main
its like stating the obvious but seems a little more clear.
The sample code, which is approved as an answer here is correct, but I disagree with it. It does not shows what is happening and I'm going to show you a good example to understand how actually the JVM works:
package test;
class A {
A() {
print();
}
void print() {
System.out.println("A");
}
}
class B extends A {
static int staticVariable2 = 123456;
static int staticVariable;
static
{
System.out.println(staticVariable2);
System.out.println("Static Initialization block");
staticVariable = Math.round(3.5f);
}
int instanceVariable;
{
System.out.println("Initialization block");
instanceVariable = Math.round(3.5f);
staticVariable = Math.round(3.5f);
}
B() {
System.out.println("Constructor");
}
public static void main(String[] args) {
A a = new B();
a.print();
System.out.println("main");
}
void print() {
System.out.println(instanceVariable);
}
static void somethingElse() {
System.out.println("Static method");
}
}
Before to start commenting on the source code, I'll give you a short explanation of static variables of a class:
First thing is that they are called class variables, they belong to the class not to particular instance of the class. All instances of the class share this static(class) variable. Each and every variable has a default value, depending on primitive or reference type. Another thing is when you reassign the static variable in some of the members of the class (initialization blocks, constructors, methods, properties) and doing so you are changing the value of the static variable not for particular instance, you are changing it for all instances. To conclude static part I will say that the static variables of a class are created not when you instantiate for first time the class, they are created when you define your class, they exist in JVM without the need of any instances. Therefor the correct access of static members from external class (class in which they are not defined) is by using the class name following by dot and then the static member, which you want to access (template: <CLASS_NAME>.<STATIC_VARIABLE_NAME>).
Now let's look at the code above:
The entry point is the main method - there are just three lines of code. I want to refer to the example which is currently approved. According to it the first thing which must be printed after printing "Static Initialization block" is "Initialization block" and here is my disagreement, the non-static initialization block is not called before the constructor, it is called before any initializations of the constructors of the class in which the initialization block is defined. The constructor of the class is the first thing involved when you create an object (instance of the class) and then when you enter the constructor the first part called is either implicit (default) super constructor or explicit super constructor or explicit call to another overloaded constructor (but at some point if there is a chain of overloaded constructors, the last one calls a super constructor, implicitly or explicitly).
There is polymorphic creation of an object, but before to enter the class B and its main method, the JVM initializes all class(static) variables, then goes through the static initialization blocks if any exist and then enters the class B and starts with the execution of the main method. It goes to the constructor of class B then immediately (implicitly) calls constructor of class A, using polymorphism the method(overridden method) called in the body of the constructor of class A is the one which is defined in class B and in this case the variable named instanceVariable is used before reinitialization. After closing the constructor of class B the thread is returned to constructor of class B but it goes first to the non-static initialization block before printing "Constructor". For better understanding debug it with some IDE, I prefer Eclipse.
Initializer block contains the code that is always executed whenever
an instance is created. It is used to declare/initialise the common
part of various constructors of a class.
The order of initialization constructors and initializer block doesn’t matter, initializer block is always executed before constructor.
What if we want to execute some code once for all objects of a class?
We use Static Block in Java.
In addition to what was said in previous answers, blocks can be synchronized .. never felt I need to use it, however,it's there
Initialization blocks are executed whenever the class is initialized and before constructors are invoked. They are typically placed above the constructors within braces. It is not at all necessary to include them in your classes.
They are typically used to initialize reference variables. This page gives a good explanation
The question is not entirely clear, but here's a brief description of ways you can initialise data in an object. Let's suppose you have a class A that holds a list of objects.
1) Put initial values in the field declaration:
class A {
private List<Object> data = new ArrayList<Object>();
}
2) Assign initial values in the constructor:
class A {
private List<Object> data;
public A() {
data = new ArrayList<Object>();
}
}
These both assume that you do not want to pass "data" as a constructor argument.
Things get a little tricky if you mix overloaded constructors with internal data like above. Consider:
class B {
private List<Object> data;
private String name;
private String userFriendlyName;
public B() {
data = new ArrayList<Object>();
name = "Default name";
userFriendlyName = "Default user friendly name";
}
public B(String name) {
data = new ArrayList<Object>();
this.name = name;
userFriendlyName = name;
}
public B(String name, String userFriendlyName) {
data = new ArrayList<Object>();
this.name = name;
this.userFriendlyName = userFriendlyName;
}
}
Notice that there is a lot of repeated code. You can fix this by making constructors call each other, or you can have a private initialisation method that each constructor calls:
class B {
private List<Object> data;
private String name;
private String userFriendlyName;
public B() {
this("Default name", "Default user friendly name");
}
public B(String name) {
this(name, name);
}
public B(String name, String userFriendlyName) {
data = new ArrayList<Object>();
this.name = name;
this.userFriendlyName = userFriendlyName;
}
}
or
class B {
private List<Object> data;
private String name;
private String userFriendlyName;
public B() {
init("Default name", "Default user friendly name");
}
public B(String name) {
init(name, name);
}
public B(String name, String userFriendlyName) {
init(name, userFriendlyName);
}
private void init(String _name, String _userFriendlyName) {
data = new ArrayList<Object>();
this.name = name;
this.userFriendlyName = userFriendlyName;
}
}
The two are (more or less) equivalent.
I hope that gives you some hints on how to initialise data in your objects. I won't talk about static initialisation blocks as that's probably a bit advanced at the moment.
EDIT: I've interpreted your question as "how do I initialise my instance variables", not "how do initialiser blocks work" as initialiser blocks are a relatively advanced concept, and from the tone of the question it seems you're asking about the simpler concept. I could be wrong.
public class StaticInitializationBlock {
static int staticVariable;
int instanceVariable;
// Static Initialization Block
static {
System.out.println("Static block");
staticVariable = 5;
}
// Instance Initialization Block
{
instanceVariable = 7;
System.out.println("Instance Block");
System.out.println(staticVariable);
System.out.println(instanceVariable);
staticVariable = 10;
}
public StaticInitializationBlock() {
System.out.println("Constructor");
}
public static void main(String[] args) {
new StaticInitializationBlock();
new StaticInitializationBlock();
}
}
Output:
Static block
Instance Block
5
7
Constructor
Instance Block
10
7
Constructor
Just to add to the excellent answers from #aioobe and #Biman Tripathy.
A static initializer is the equivalent of a constructor in the static context. which is needed to setup the static environment.
A instance initializer is best for anonymous inner classes.
It is also possible to have multiple initializer blocks in class
When we have multiple initializer blocks they are executed (actually copied to constructors by JVM) in the order they appear
Order of initializer blocks matters, but order of initializer blocks mixed with Constructors doesn't
Abstract classes can also have both static and instance initializer blocks.
Code Demo -
abstract class Aircraft {
protected Integer seatCapacity;
{ // Initial block 1, Before Constructor
System.out.println("Executing: Initial Block 1");
}
Aircraft() {
System.out.println("Executing: Aircraft constructor");
}
{ // Initial block 2, After Constructor
System.out.println("Executing: Initial Block 2");
}
}
class SupersonicAircraft extends Aircraft {
{ // Initial block 3, Internalizing a instance variable
seatCapacity = 300;
System.out.println("Executing: Initial Block 3");
}
{ // Initial block 4
System.out.println("Executing: Initial Block 4");
}
SupersonicAircraft() {
System.out.println("Executing: SupersonicAircraft constructor");
}
}
An instance creation of SupersonicAircraft will produce logs in below order
Executing: Initial Block 1
Executing: Initial Block 2
Executing: Aircraft constructor
Executing: Initial Block 3
Executing: Initial Block 4
Executing: SupersonicAircraft constructor
Seat Capacity - 300
Edited:
I need to change the values of several variables as they run several times thorugh a timer. I need to keep updating the values with every iteration through the timer. I cannot set the values to final as that will prevent me from updating the values however I am getting the error I describe in the initial question below:
I had previously written what is below:
I am getting the error "cannot refer to a non-final variable inside an inner class defined in a different method".
This is happening for the double called price and the Price called priceObject. Do you know why I get this problem. I do not understand why I need to have a final declaration. Also if you can see what it is I am trying to do, what do I have to do to get around this problem.
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
double lastPrice = 0;
Price priceObject = new Price();
double price = 0;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
price = priceObject.getNextPrice(lastPrice);
System.out.println();
lastPrice = price;
}
}, delay, period);
}
Java doesn't support true closures, even though using an anonymous class like you are using here (new TimerTask() { ... }) looks like a kind of closure.
edit - See the comments below - the following is not a correct explanation, as KeeperOfTheSoul points out.
This is why it doesn't work:
The variables lastPrice and price are local variables in the main() method. The object that you create with the anonymous class might last until after the main() method returns.
When the main() method returns, local variables (such as lastPrice and price) will be cleaned up from the stack, so they won't exist anymore after main() returns.
But the anonymous class object references these variables. Things would go horribly wrong if the anonymous class object tries to access the variables after they have been cleaned up.
By making lastPrice and price final, they are not really variables anymore, but constants. The compiler can then just replace the use of lastPrice and price in the anonymous class with the values of the constants (at compile time, of course), and you won't have the problem with accessing non-existent variables anymore.
Other programming languages that do support closures do it by treating those variables specially - by making sure they don't get destroyed when the method ends, so that the closure can still access the variables.
#Ankur: You could do this:
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
// Variables as member variables instead of local variables in main()
private double lastPrice = 0;
private Price priceObject = new Price();
private double price = 0;
public void run() {
price = priceObject.getNextPrice(lastPrice);
System.out.println();
lastPrice = price;
}
}, delay, period);
}
To avoid strange side-effects with closures in java variables referenced by an anonymous delegate must be marked as final, so to refer to lastPrice and price within the timer task they need to be marked as final.
This obviously won't work for you because you wish to change them, in this case you should look at encapsulating them within a class.
public class Foo {
private PriceObject priceObject;
private double lastPrice;
private double price;
public Foo(PriceObject priceObject) {
this.priceObject = priceObject;
}
public void tick() {
price = priceObject.getNextPrice(lastPrice);
lastPrice = price;
}
}
now just create a new Foo as final and call .tick from the timer.
public static void main(String args[]){
int period = 2000;
int delay = 2000;
Price priceObject = new Price();
final Foo foo = new Foo(priceObject);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
foo.tick();
}
}, delay, period);
}
You can only access final variables from the containing class when using an anonymous class. Therefore you need to declare the variables being used final (which is not an option for you since you are changing lastPrice and price), or don't use an anonymous class.
So your options are to create an actual inner class, in which you can pass in the variables and use them in a normal fashion
or:
There is a quick (and in my opinion ugly) hack for your lastPrice and price variable which is to declare it like so
final double lastPrice[1];
final double price[1];
and in your anonymous class you can set the value like this
price[0] = priceObject.getNextPrice(lastPrice[0]);
System.out.println();
lastPrice[0] = price[0];
Good explanations for why you can't do what you're trying to do already provided. As a solution, maybe consider:
public class foo
{
static class priceInfo
{
public double lastPrice = 0;
public double price = 0;
public Price priceObject = new Price ();
}
public static void main ( String args[] )
{
int period = 2000;
int delay = 2000;
final priceInfo pi = new priceInfo ();
Timer timer = new Timer ();
timer.scheduleAtFixedRate ( new TimerTask ()
{
public void run ()
{
pi.price = pi.priceObject.getNextPrice ( pi.lastPrice );
System.out.println ();
pi.lastPrice = pi.price;
}
}, delay, period );
}
}
Seems like probably you could do a better design than that, but the idea is that you could group the updated variables inside a class reference that doesn't change.
With anonymous classes, you are actually declaring a "nameless" nested class. For nested classes, the compiler generates a new standalone public class with a constructor that will take all the variables it uses as arguments (for "named" nested classes, this is always an instance of the original/enclosing class). This is done because the runtime environment has no notion of nested classes, so there needs to be a (automatic) conversion from a nested to a standalone class.
Take this code for example:
public class EnclosingClass {
public void someMethod() {
String shared = "hello";
new Thread() {
public void run() {
// this is not valid, won't compile
System.out.println(shared); // this instance expects shared to point to the reference where the String object "hello" lives in heap
}
}.start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
}
That won't work, because this is what the compiler does under the hood:
public void someMethod() {
String shared = "hello";
new EnclosingClass$1(shared).start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
The original anonymous class is replaced by some standalone class that the compiler generates (code is not exact, but should give you a good idea):
public class EnclosingClass$1 extends Thread {
String shared;
public EnclosingClass$1(String shared) {
this.shared = shared;
}
public void run() {
System.out.println(shared);
}
}
As you can see, the standalone class holds a reference to the shared object, remember that everything in java is pass-by-value, so even if the reference variable 'shared' in EnclosingClass gets changed, the instance it points to is not modified, and all other reference variables pointing to it (like the one in the anonymous class: Enclosing$1), will not be aware of this. This is the main reason the compiler forces you to declare this 'shared' variables as final, so that this type of behavior won't make it into your already running code.
Now, this is what happens when you use an instance variable inside an anonymous class (this is what you should do to solve your problem, move your logic to an "instance" method or a constructor of a class):
public class EnclosingClass {
String shared = "hello";
public void someMethod() {
new Thread() {
public void run() {
System.out.println(shared); // this is perfectly valid
}
}.start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
}
This compiles fine, because the compiler will modify the code, so that the new generated class Enclosing$1 will hold a reference to the instance of EnclosingClass where it was instantiated (this is only a representation, but should get you going):
public void someMethod() {
new EnclosingClass$1(this).start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
public class EnclosingClass$1 extends Thread {
EnclosingClass enclosing;
public EnclosingClass$1(EnclosingClass enclosing) {
this.enclosing = enclosing;
}
public void run() {
System.out.println(enclosing.shared);
}
}
Like this, when the reference variable 'shared' in EnclosingClass gets reassigned, and this happens before the call to Thread#run(), you'll see "other hello" printed twice, because now EnclosingClass$1#enclosing variable will keep a reference to the object of the class where it was declared, so changes to any attribute on that object will be visible to instances of EnclosingClass$1.
For more information on the subject, you can see this excelent blog post (not written by me): http://kevinboone.net/java_inner.html
When I stumble upon this issue, I just pass the objects to the inner class through the constructor. If I need to pass primitives or immutable objects (as in this case), a wrapper class is needed.
Edit: Actually, I don't use an anonymous class at all, but a proper subclass:
public class PriceData {
private double lastPrice = 0;
private double price = 0;
public void setlastPrice(double lastPrice) {
this.lastPrice = lastPrice;
}
public double getLastPrice() {
return lastPrice;
}
public void setPrice(double price) {
this.price = price;
}
public double getPrice() {
return price;
}
}
public class PriceTimerTask extends TimerTask {
private PriceData priceData;
private Price priceObject;
public PriceTimerTask(PriceData priceData, Price priceObject) {
this.priceData = priceData;
this.priceObject = priceObject;
}
public void run() {
priceData.setPrice(priceObject.getNextPrice(lastPrice));
System.out.println();
priceData.setLastPrice(priceData.getPrice());
}
}
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
PriceData priceData = new PriceData();
Price priceObject = new Price();
Timer timer = new Timer();
timer.scheduleAtFixedRate(new PriceTimerTask(priceData, priceObject), delay, period);
}
You cannot refer to non-final variables because Java Language Specification says so. From 8.1.3:
"Any local variable, formal method parameter or exception handler parameter used but not declared in an inner class must be declared final." Whole paragraph.
I can see only part of your code - according to me scheduling modification of local variables is a strange idea. Local variables cease to exist when you leave the function. Maybe static fields of a class would be better?
I just wrote something to handle something along the authors intention.
I found the best thing to do was to let the constructor take all the objects and then in your implemented method use that constructor objects.
However, if you are writing a generic interface class, then you have to pass an Object, or better a list of Objects. This could be done by Object[] or even better, Object ... because it is easier to call.
See my example piece just below.
List<String> lst = new ArrayList<String>();
lst.add("1");
lst.add("2");
SomeAbstractClass p = new SomeAbstractClass (lst, "another parameter", 20, true) {
public void perform( ) {
ArrayList<String> lst = (ArrayList<String>)getArgs()[0];
}
};
public abstract class SomeAbstractClass{
private Object[] args;
public SomeAbstractClass(Object ... args) {
this.args = args;
}
public abstract void perform();
public Object[] getArgs() {
return args;
}
}
Please see this post about Java closures that supports this out of the box:
http://mseifed.blogspot.se/2012/09/closure-implementation-for-java-5-6-and.html
Version 1 supports passing of non-final closures with autocasting:
https://github.com/MSeifeddo/Closure-implementation-for-Java-5-6-and-7/blob/master/org/mo/closure/v1/Closure.java
SortedSet<String> sortedNames = new TreeSet<String>();
// NOTE! Instead of enforcing final, we pass it through the constructor
eachLine(randomFile0, new V1<String>(sortedNames) {
public void call(String line) {
SortedSet<String> sortedNames = castFirst(); // Read contructor arg zero, and auto cast it
sortedNames.add(extractName(line));
}
});
If you want to change a value in a method call within an anonymous class, that "value" is actually a Future. So, if you use Guava, you can write
...
final SettableFuture<Integer> myvalue = SettableFuture<Integer>.create();
...
someclass.run(new Runnable(){
public void run(){
...
myvalue.set(value);
...
}
}
return myvalue.get();
One solution I have noticed isn't mentioned (unless I missed it, if I did please correct me), is the use of a class variable. Ran into this issue attempting to run a new thread within a method: new Thread(){ Do Something }.
Calling doSomething() from the following will work. You do not necessarily have to declare it final, just need to change the scope of the variable so it is not collected before the innerclass. This is unless of course your process is huge and changing the scope might create some sort of conflict. I didn't want to make my variable final as it was in no way a final/constant.
public class Test
{
protected String var1;
protected String var2;
public void doSomething()
{
new Thread()
{
public void run()
{
System.out.println("In Thread variable 1: " + var1);
System.out.println("In Thread variable 2: " + var2);
}
}.start();
}
}
you can just declare the variable outside the outer class. After this, you will be able to edit the variable from within the inner class. I sometimes face similar problems while coding in android so I declare the variable as global and it works for me.
If the variable required to be final, cannot be then you can assign the value of the variable to another variable and make THAT final so you can use it instead.
use ClassName.this.variableName to reference the non-final variable
Can you make lastPrice, priceObject, and price fields of the anonymous inner class?
The main concern is whether a variable inside the anonymous class instance can be resolved at run-time. It is not a must to make a variable final as long as it is guaranteed that the variable is inside the run-time scope. For example, please see the two variables _statusMessage and _statusTextView inside updateStatus() method.
public class WorkerService extends Service {
Worker _worker;
ExecutorService _executorService;
ScheduledExecutorService _scheduledStopService;
TextView _statusTextView;
#Override
public void onCreate() {
_worker = new Worker(this);
_worker.monitorGpsInBackground();
// To get a thread pool service containing merely one thread
_executorService = Executors.newSingleThreadExecutor();
// schedule something to run in the future
_scheduledStopService = Executors.newSingleThreadScheduledExecutor();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
ServiceRunnable runnable = new ServiceRunnable(this, startId);
_executorService.execute(runnable);
// the return value tells what the OS should
// do if this service is killed for resource reasons
// 1. START_STICKY: the OS restarts the service when resources become
// available by passing a null intent to onStartCommand
// 2. START_REDELIVER_INTENT: the OS restarts the service when resources
// become available by passing the last intent that was passed to the
// service before it was killed to onStartCommand
// 3. START_NOT_STICKY: just wait for next call to startService, no
// auto-restart
return Service.START_NOT_STICKY;
}
#Override
public void onDestroy() {
_worker.stopGpsMonitoring();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
class ServiceRunnable implements Runnable {
WorkerService _theService;
int _startId;
String _statusMessage;
public ServiceRunnable(WorkerService theService, int startId) {
_theService = theService;
_startId = startId;
}
#Override
public void run() {
_statusTextView = MyActivity.getActivityStatusView();
// get most recently available location as a latitude /
// longtitude
Location location = _worker.getLocation();
updateStatus("Starting");
// convert lat/lng to a human-readable address
String address = _worker.reverseGeocode(location);
updateStatus("Reverse geocoding");
// Write the location and address out to a file
_worker.save(location, address, "ResponsiveUx.out");
updateStatus("Done");
DelayedStopRequest stopRequest = new DelayedStopRequest(_theService, _startId);
// schedule a stopRequest after 10 seconds
_theService._scheduledStopService.schedule(stopRequest, 10, TimeUnit.SECONDS);
}
void updateStatus(String message) {
_statusMessage = message;
if (_statusTextView != null) {
_statusTextView.post(new Runnable() {
#Override
public void run() {
_statusTextView.setText(_statusMessage);
}
});
}
}
}
what worked for me is just define the variable outside this function of your.
Just before main function declare i.e.
Double price;
public static void main(String []args(){
--------
--------
}
Declare the variable as a static and reference it in the required method using className.variable
Just an another explanation. Consider this example below
public class Outer{
public static void main(String[] args){
Outer o = new Outer();
o.m1();
o=null;
}
public void m1(){
//int x = 10;
class Inner{
Thread t = new Thread(new Runnable(){
public void run(){
for(int i=0;i<10;i++){
try{
Thread.sleep(2000);
}catch(InterruptedException e){
//handle InterruptedException e
}
System.out.println("Thread t running");
}
}
});
}
new Inner().t.start();
System.out.println("m1 Completes");
}
}
Here Output will be
m1 Completes
Thread t running
Thread t running
Thread t running
................
Now method m1() completes and we assign reference variable o to null , Now Outer Class Object is eligible for GC but Inner Class Object is still exist who has (Has-A) relationship with Thread object which is running. Without existing Outer class object there is no chance of existing m1() method and without existing m1() method there is no chance of existing its local variable but if Inner Class Object uses the local variable of m1() method then everything is self explanatory.
To solve this we have to create a copy of local variable and then have to copy then into the heap with Inner class object, what java does for only final variable because they are not actually variable they are like constants(Everything happens at compile time only not at runtime).
To solve the problem above, different languages make different decisions.
for Java, the solution is as what we see in this article.
for C#, the solution is allow side-effects and capture by reference is the only option.
for C++11, the solution is to allow the programmer make the decision. They can choose to capture by value or by reference. If capturing by value, no side-effects would occur because the variable referenced is actually different. If capture by reference, side-effects may occur but the programmer should realize it.
Because it's confusing if the variable isn't final, as the changes to it won't be picked up in the anonymous class.
Just make the variables 'price' and 'lastPrice' final.
-- Edit
Oops, and you'll also need to not assign to them, obviously, in your function. You'll need new local variables. Anyway, I suspect someone has given you a better answer by now.
Edited:
I need to change the values of several variables as they run several times thorugh a timer. I need to keep updating the values with every iteration through the timer. I cannot set the values to final as that will prevent me from updating the values however I am getting the error I describe in the initial question below:
I had previously written what is below:
I am getting the error "cannot refer to a non-final variable inside an inner class defined in a different method".
This is happening for the double called price and the Price called priceObject. Do you know why I get this problem. I do not understand why I need to have a final declaration. Also if you can see what it is I am trying to do, what do I have to do to get around this problem.
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
double lastPrice = 0;
Price priceObject = new Price();
double price = 0;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
price = priceObject.getNextPrice(lastPrice);
System.out.println();
lastPrice = price;
}
}, delay, period);
}
Java doesn't support true closures, even though using an anonymous class like you are using here (new TimerTask() { ... }) looks like a kind of closure.
edit - See the comments below - the following is not a correct explanation, as KeeperOfTheSoul points out.
This is why it doesn't work:
The variables lastPrice and price are local variables in the main() method. The object that you create with the anonymous class might last until after the main() method returns.
When the main() method returns, local variables (such as lastPrice and price) will be cleaned up from the stack, so they won't exist anymore after main() returns.
But the anonymous class object references these variables. Things would go horribly wrong if the anonymous class object tries to access the variables after they have been cleaned up.
By making lastPrice and price final, they are not really variables anymore, but constants. The compiler can then just replace the use of lastPrice and price in the anonymous class with the values of the constants (at compile time, of course), and you won't have the problem with accessing non-existent variables anymore.
Other programming languages that do support closures do it by treating those variables specially - by making sure they don't get destroyed when the method ends, so that the closure can still access the variables.
#Ankur: You could do this:
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
// Variables as member variables instead of local variables in main()
private double lastPrice = 0;
private Price priceObject = new Price();
private double price = 0;
public void run() {
price = priceObject.getNextPrice(lastPrice);
System.out.println();
lastPrice = price;
}
}, delay, period);
}
To avoid strange side-effects with closures in java variables referenced by an anonymous delegate must be marked as final, so to refer to lastPrice and price within the timer task they need to be marked as final.
This obviously won't work for you because you wish to change them, in this case you should look at encapsulating them within a class.
public class Foo {
private PriceObject priceObject;
private double lastPrice;
private double price;
public Foo(PriceObject priceObject) {
this.priceObject = priceObject;
}
public void tick() {
price = priceObject.getNextPrice(lastPrice);
lastPrice = price;
}
}
now just create a new Foo as final and call .tick from the timer.
public static void main(String args[]){
int period = 2000;
int delay = 2000;
Price priceObject = new Price();
final Foo foo = new Foo(priceObject);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
foo.tick();
}
}, delay, period);
}
You can only access final variables from the containing class when using an anonymous class. Therefore you need to declare the variables being used final (which is not an option for you since you are changing lastPrice and price), or don't use an anonymous class.
So your options are to create an actual inner class, in which you can pass in the variables and use them in a normal fashion
or:
There is a quick (and in my opinion ugly) hack for your lastPrice and price variable which is to declare it like so
final double lastPrice[1];
final double price[1];
and in your anonymous class you can set the value like this
price[0] = priceObject.getNextPrice(lastPrice[0]);
System.out.println();
lastPrice[0] = price[0];
Good explanations for why you can't do what you're trying to do already provided. As a solution, maybe consider:
public class foo
{
static class priceInfo
{
public double lastPrice = 0;
public double price = 0;
public Price priceObject = new Price ();
}
public static void main ( String args[] )
{
int period = 2000;
int delay = 2000;
final priceInfo pi = new priceInfo ();
Timer timer = new Timer ();
timer.scheduleAtFixedRate ( new TimerTask ()
{
public void run ()
{
pi.price = pi.priceObject.getNextPrice ( pi.lastPrice );
System.out.println ();
pi.lastPrice = pi.price;
}
}, delay, period );
}
}
Seems like probably you could do a better design than that, but the idea is that you could group the updated variables inside a class reference that doesn't change.
With anonymous classes, you are actually declaring a "nameless" nested class. For nested classes, the compiler generates a new standalone public class with a constructor that will take all the variables it uses as arguments (for "named" nested classes, this is always an instance of the original/enclosing class). This is done because the runtime environment has no notion of nested classes, so there needs to be a (automatic) conversion from a nested to a standalone class.
Take this code for example:
public class EnclosingClass {
public void someMethod() {
String shared = "hello";
new Thread() {
public void run() {
// this is not valid, won't compile
System.out.println(shared); // this instance expects shared to point to the reference where the String object "hello" lives in heap
}
}.start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
}
That won't work, because this is what the compiler does under the hood:
public void someMethod() {
String shared = "hello";
new EnclosingClass$1(shared).start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
The original anonymous class is replaced by some standalone class that the compiler generates (code is not exact, but should give you a good idea):
public class EnclosingClass$1 extends Thread {
String shared;
public EnclosingClass$1(String shared) {
this.shared = shared;
}
public void run() {
System.out.println(shared);
}
}
As you can see, the standalone class holds a reference to the shared object, remember that everything in java is pass-by-value, so even if the reference variable 'shared' in EnclosingClass gets changed, the instance it points to is not modified, and all other reference variables pointing to it (like the one in the anonymous class: Enclosing$1), will not be aware of this. This is the main reason the compiler forces you to declare this 'shared' variables as final, so that this type of behavior won't make it into your already running code.
Now, this is what happens when you use an instance variable inside an anonymous class (this is what you should do to solve your problem, move your logic to an "instance" method or a constructor of a class):
public class EnclosingClass {
String shared = "hello";
public void someMethod() {
new Thread() {
public void run() {
System.out.println(shared); // this is perfectly valid
}
}.start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
}
This compiles fine, because the compiler will modify the code, so that the new generated class Enclosing$1 will hold a reference to the instance of EnclosingClass where it was instantiated (this is only a representation, but should get you going):
public void someMethod() {
new EnclosingClass$1(this).start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
public class EnclosingClass$1 extends Thread {
EnclosingClass enclosing;
public EnclosingClass$1(EnclosingClass enclosing) {
this.enclosing = enclosing;
}
public void run() {
System.out.println(enclosing.shared);
}
}
Like this, when the reference variable 'shared' in EnclosingClass gets reassigned, and this happens before the call to Thread#run(), you'll see "other hello" printed twice, because now EnclosingClass$1#enclosing variable will keep a reference to the object of the class where it was declared, so changes to any attribute on that object will be visible to instances of EnclosingClass$1.
For more information on the subject, you can see this excelent blog post (not written by me): http://kevinboone.net/java_inner.html
When I stumble upon this issue, I just pass the objects to the inner class through the constructor. If I need to pass primitives or immutable objects (as in this case), a wrapper class is needed.
Edit: Actually, I don't use an anonymous class at all, but a proper subclass:
public class PriceData {
private double lastPrice = 0;
private double price = 0;
public void setlastPrice(double lastPrice) {
this.lastPrice = lastPrice;
}
public double getLastPrice() {
return lastPrice;
}
public void setPrice(double price) {
this.price = price;
}
public double getPrice() {
return price;
}
}
public class PriceTimerTask extends TimerTask {
private PriceData priceData;
private Price priceObject;
public PriceTimerTask(PriceData priceData, Price priceObject) {
this.priceData = priceData;
this.priceObject = priceObject;
}
public void run() {
priceData.setPrice(priceObject.getNextPrice(lastPrice));
System.out.println();
priceData.setLastPrice(priceData.getPrice());
}
}
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
PriceData priceData = new PriceData();
Price priceObject = new Price();
Timer timer = new Timer();
timer.scheduleAtFixedRate(new PriceTimerTask(priceData, priceObject), delay, period);
}
You cannot refer to non-final variables because Java Language Specification says so. From 8.1.3:
"Any local variable, formal method parameter or exception handler parameter used but not declared in an inner class must be declared final." Whole paragraph.
I can see only part of your code - according to me scheduling modification of local variables is a strange idea. Local variables cease to exist when you leave the function. Maybe static fields of a class would be better?
I just wrote something to handle something along the authors intention.
I found the best thing to do was to let the constructor take all the objects and then in your implemented method use that constructor objects.
However, if you are writing a generic interface class, then you have to pass an Object, or better a list of Objects. This could be done by Object[] or even better, Object ... because it is easier to call.
See my example piece just below.
List<String> lst = new ArrayList<String>();
lst.add("1");
lst.add("2");
SomeAbstractClass p = new SomeAbstractClass (lst, "another parameter", 20, true) {
public void perform( ) {
ArrayList<String> lst = (ArrayList<String>)getArgs()[0];
}
};
public abstract class SomeAbstractClass{
private Object[] args;
public SomeAbstractClass(Object ... args) {
this.args = args;
}
public abstract void perform();
public Object[] getArgs() {
return args;
}
}
Please see this post about Java closures that supports this out of the box:
http://mseifed.blogspot.se/2012/09/closure-implementation-for-java-5-6-and.html
Version 1 supports passing of non-final closures with autocasting:
https://github.com/MSeifeddo/Closure-implementation-for-Java-5-6-and-7/blob/master/org/mo/closure/v1/Closure.java
SortedSet<String> sortedNames = new TreeSet<String>();
// NOTE! Instead of enforcing final, we pass it through the constructor
eachLine(randomFile0, new V1<String>(sortedNames) {
public void call(String line) {
SortedSet<String> sortedNames = castFirst(); // Read contructor arg zero, and auto cast it
sortedNames.add(extractName(line));
}
});
If you want to change a value in a method call within an anonymous class, that "value" is actually a Future. So, if you use Guava, you can write
...
final SettableFuture<Integer> myvalue = SettableFuture<Integer>.create();
...
someclass.run(new Runnable(){
public void run(){
...
myvalue.set(value);
...
}
}
return myvalue.get();
One solution I have noticed isn't mentioned (unless I missed it, if I did please correct me), is the use of a class variable. Ran into this issue attempting to run a new thread within a method: new Thread(){ Do Something }.
Calling doSomething() from the following will work. You do not necessarily have to declare it final, just need to change the scope of the variable so it is not collected before the innerclass. This is unless of course your process is huge and changing the scope might create some sort of conflict. I didn't want to make my variable final as it was in no way a final/constant.
public class Test
{
protected String var1;
protected String var2;
public void doSomething()
{
new Thread()
{
public void run()
{
System.out.println("In Thread variable 1: " + var1);
System.out.println("In Thread variable 2: " + var2);
}
}.start();
}
}
you can just declare the variable outside the outer class. After this, you will be able to edit the variable from within the inner class. I sometimes face similar problems while coding in android so I declare the variable as global and it works for me.
If the variable required to be final, cannot be then you can assign the value of the variable to another variable and make THAT final so you can use it instead.
use ClassName.this.variableName to reference the non-final variable
Can you make lastPrice, priceObject, and price fields of the anonymous inner class?
The main concern is whether a variable inside the anonymous class instance can be resolved at run-time. It is not a must to make a variable final as long as it is guaranteed that the variable is inside the run-time scope. For example, please see the two variables _statusMessage and _statusTextView inside updateStatus() method.
public class WorkerService extends Service {
Worker _worker;
ExecutorService _executorService;
ScheduledExecutorService _scheduledStopService;
TextView _statusTextView;
#Override
public void onCreate() {
_worker = new Worker(this);
_worker.monitorGpsInBackground();
// To get a thread pool service containing merely one thread
_executorService = Executors.newSingleThreadExecutor();
// schedule something to run in the future
_scheduledStopService = Executors.newSingleThreadScheduledExecutor();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
ServiceRunnable runnable = new ServiceRunnable(this, startId);
_executorService.execute(runnable);
// the return value tells what the OS should
// do if this service is killed for resource reasons
// 1. START_STICKY: the OS restarts the service when resources become
// available by passing a null intent to onStartCommand
// 2. START_REDELIVER_INTENT: the OS restarts the service when resources
// become available by passing the last intent that was passed to the
// service before it was killed to onStartCommand
// 3. START_NOT_STICKY: just wait for next call to startService, no
// auto-restart
return Service.START_NOT_STICKY;
}
#Override
public void onDestroy() {
_worker.stopGpsMonitoring();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
class ServiceRunnable implements Runnable {
WorkerService _theService;
int _startId;
String _statusMessage;
public ServiceRunnable(WorkerService theService, int startId) {
_theService = theService;
_startId = startId;
}
#Override
public void run() {
_statusTextView = MyActivity.getActivityStatusView();
// get most recently available location as a latitude /
// longtitude
Location location = _worker.getLocation();
updateStatus("Starting");
// convert lat/lng to a human-readable address
String address = _worker.reverseGeocode(location);
updateStatus("Reverse geocoding");
// Write the location and address out to a file
_worker.save(location, address, "ResponsiveUx.out");
updateStatus("Done");
DelayedStopRequest stopRequest = new DelayedStopRequest(_theService, _startId);
// schedule a stopRequest after 10 seconds
_theService._scheduledStopService.schedule(stopRequest, 10, TimeUnit.SECONDS);
}
void updateStatus(String message) {
_statusMessage = message;
if (_statusTextView != null) {
_statusTextView.post(new Runnable() {
#Override
public void run() {
_statusTextView.setText(_statusMessage);
}
});
}
}
}
what worked for me is just define the variable outside this function of your.
Just before main function declare i.e.
Double price;
public static void main(String []args(){
--------
--------
}
Declare the variable as a static and reference it in the required method using className.variable
Just an another explanation. Consider this example below
public class Outer{
public static void main(String[] args){
Outer o = new Outer();
o.m1();
o=null;
}
public void m1(){
//int x = 10;
class Inner{
Thread t = new Thread(new Runnable(){
public void run(){
for(int i=0;i<10;i++){
try{
Thread.sleep(2000);
}catch(InterruptedException e){
//handle InterruptedException e
}
System.out.println("Thread t running");
}
}
});
}
new Inner().t.start();
System.out.println("m1 Completes");
}
}
Here Output will be
m1 Completes
Thread t running
Thread t running
Thread t running
................
Now method m1() completes and we assign reference variable o to null , Now Outer Class Object is eligible for GC but Inner Class Object is still exist who has (Has-A) relationship with Thread object which is running. Without existing Outer class object there is no chance of existing m1() method and without existing m1() method there is no chance of existing its local variable but if Inner Class Object uses the local variable of m1() method then everything is self explanatory.
To solve this we have to create a copy of local variable and then have to copy then into the heap with Inner class object, what java does for only final variable because they are not actually variable they are like constants(Everything happens at compile time only not at runtime).
To solve the problem above, different languages make different decisions.
for Java, the solution is as what we see in this article.
for C#, the solution is allow side-effects and capture by reference is the only option.
for C++11, the solution is to allow the programmer make the decision. They can choose to capture by value or by reference. If capturing by value, no side-effects would occur because the variable referenced is actually different. If capture by reference, side-effects may occur but the programmer should realize it.
Because it's confusing if the variable isn't final, as the changes to it won't be picked up in the anonymous class.
Just make the variables 'price' and 'lastPrice' final.
-- Edit
Oops, and you'll also need to not assign to them, obviously, in your function. You'll need new local variables. Anyway, I suspect someone has given you a better answer by now.
Edited:
I need to change the values of several variables as they run several times thorugh a timer. I need to keep updating the values with every iteration through the timer. I cannot set the values to final as that will prevent me from updating the values however I am getting the error I describe in the initial question below:
I had previously written what is below:
I am getting the error "cannot refer to a non-final variable inside an inner class defined in a different method".
This is happening for the double called price and the Price called priceObject. Do you know why I get this problem. I do not understand why I need to have a final declaration. Also if you can see what it is I am trying to do, what do I have to do to get around this problem.
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
double lastPrice = 0;
Price priceObject = new Price();
double price = 0;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
price = priceObject.getNextPrice(lastPrice);
System.out.println();
lastPrice = price;
}
}, delay, period);
}
Java doesn't support true closures, even though using an anonymous class like you are using here (new TimerTask() { ... }) looks like a kind of closure.
edit - See the comments below - the following is not a correct explanation, as KeeperOfTheSoul points out.
This is why it doesn't work:
The variables lastPrice and price are local variables in the main() method. The object that you create with the anonymous class might last until after the main() method returns.
When the main() method returns, local variables (such as lastPrice and price) will be cleaned up from the stack, so they won't exist anymore after main() returns.
But the anonymous class object references these variables. Things would go horribly wrong if the anonymous class object tries to access the variables after they have been cleaned up.
By making lastPrice and price final, they are not really variables anymore, but constants. The compiler can then just replace the use of lastPrice and price in the anonymous class with the values of the constants (at compile time, of course), and you won't have the problem with accessing non-existent variables anymore.
Other programming languages that do support closures do it by treating those variables specially - by making sure they don't get destroyed when the method ends, so that the closure can still access the variables.
#Ankur: You could do this:
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
// Variables as member variables instead of local variables in main()
private double lastPrice = 0;
private Price priceObject = new Price();
private double price = 0;
public void run() {
price = priceObject.getNextPrice(lastPrice);
System.out.println();
lastPrice = price;
}
}, delay, period);
}
To avoid strange side-effects with closures in java variables referenced by an anonymous delegate must be marked as final, so to refer to lastPrice and price within the timer task they need to be marked as final.
This obviously won't work for you because you wish to change them, in this case you should look at encapsulating them within a class.
public class Foo {
private PriceObject priceObject;
private double lastPrice;
private double price;
public Foo(PriceObject priceObject) {
this.priceObject = priceObject;
}
public void tick() {
price = priceObject.getNextPrice(lastPrice);
lastPrice = price;
}
}
now just create a new Foo as final and call .tick from the timer.
public static void main(String args[]){
int period = 2000;
int delay = 2000;
Price priceObject = new Price();
final Foo foo = new Foo(priceObject);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
foo.tick();
}
}, delay, period);
}
You can only access final variables from the containing class when using an anonymous class. Therefore you need to declare the variables being used final (which is not an option for you since you are changing lastPrice and price), or don't use an anonymous class.
So your options are to create an actual inner class, in which you can pass in the variables and use them in a normal fashion
or:
There is a quick (and in my opinion ugly) hack for your lastPrice and price variable which is to declare it like so
final double lastPrice[1];
final double price[1];
and in your anonymous class you can set the value like this
price[0] = priceObject.getNextPrice(lastPrice[0]);
System.out.println();
lastPrice[0] = price[0];
Good explanations for why you can't do what you're trying to do already provided. As a solution, maybe consider:
public class foo
{
static class priceInfo
{
public double lastPrice = 0;
public double price = 0;
public Price priceObject = new Price ();
}
public static void main ( String args[] )
{
int period = 2000;
int delay = 2000;
final priceInfo pi = new priceInfo ();
Timer timer = new Timer ();
timer.scheduleAtFixedRate ( new TimerTask ()
{
public void run ()
{
pi.price = pi.priceObject.getNextPrice ( pi.lastPrice );
System.out.println ();
pi.lastPrice = pi.price;
}
}, delay, period );
}
}
Seems like probably you could do a better design than that, but the idea is that you could group the updated variables inside a class reference that doesn't change.
With anonymous classes, you are actually declaring a "nameless" nested class. For nested classes, the compiler generates a new standalone public class with a constructor that will take all the variables it uses as arguments (for "named" nested classes, this is always an instance of the original/enclosing class). This is done because the runtime environment has no notion of nested classes, so there needs to be a (automatic) conversion from a nested to a standalone class.
Take this code for example:
public class EnclosingClass {
public void someMethod() {
String shared = "hello";
new Thread() {
public void run() {
// this is not valid, won't compile
System.out.println(shared); // this instance expects shared to point to the reference where the String object "hello" lives in heap
}
}.start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
}
That won't work, because this is what the compiler does under the hood:
public void someMethod() {
String shared = "hello";
new EnclosingClass$1(shared).start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
The original anonymous class is replaced by some standalone class that the compiler generates (code is not exact, but should give you a good idea):
public class EnclosingClass$1 extends Thread {
String shared;
public EnclosingClass$1(String shared) {
this.shared = shared;
}
public void run() {
System.out.println(shared);
}
}
As you can see, the standalone class holds a reference to the shared object, remember that everything in java is pass-by-value, so even if the reference variable 'shared' in EnclosingClass gets changed, the instance it points to is not modified, and all other reference variables pointing to it (like the one in the anonymous class: Enclosing$1), will not be aware of this. This is the main reason the compiler forces you to declare this 'shared' variables as final, so that this type of behavior won't make it into your already running code.
Now, this is what happens when you use an instance variable inside an anonymous class (this is what you should do to solve your problem, move your logic to an "instance" method or a constructor of a class):
public class EnclosingClass {
String shared = "hello";
public void someMethod() {
new Thread() {
public void run() {
System.out.println(shared); // this is perfectly valid
}
}.start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
}
This compiles fine, because the compiler will modify the code, so that the new generated class Enclosing$1 will hold a reference to the instance of EnclosingClass where it was instantiated (this is only a representation, but should get you going):
public void someMethod() {
new EnclosingClass$1(this).start();
// change the reference 'shared' points to, with a new value
shared = "other hello";
System.out.println(shared);
}
public class EnclosingClass$1 extends Thread {
EnclosingClass enclosing;
public EnclosingClass$1(EnclosingClass enclosing) {
this.enclosing = enclosing;
}
public void run() {
System.out.println(enclosing.shared);
}
}
Like this, when the reference variable 'shared' in EnclosingClass gets reassigned, and this happens before the call to Thread#run(), you'll see "other hello" printed twice, because now EnclosingClass$1#enclosing variable will keep a reference to the object of the class where it was declared, so changes to any attribute on that object will be visible to instances of EnclosingClass$1.
For more information on the subject, you can see this excelent blog post (not written by me): http://kevinboone.net/java_inner.html
When I stumble upon this issue, I just pass the objects to the inner class through the constructor. If I need to pass primitives or immutable objects (as in this case), a wrapper class is needed.
Edit: Actually, I don't use an anonymous class at all, but a proper subclass:
public class PriceData {
private double lastPrice = 0;
private double price = 0;
public void setlastPrice(double lastPrice) {
this.lastPrice = lastPrice;
}
public double getLastPrice() {
return lastPrice;
}
public void setPrice(double price) {
this.price = price;
}
public double getPrice() {
return price;
}
}
public class PriceTimerTask extends TimerTask {
private PriceData priceData;
private Price priceObject;
public PriceTimerTask(PriceData priceData, Price priceObject) {
this.priceData = priceData;
this.priceObject = priceObject;
}
public void run() {
priceData.setPrice(priceObject.getNextPrice(lastPrice));
System.out.println();
priceData.setLastPrice(priceData.getPrice());
}
}
public static void main(String args[]) {
int period = 2000;
int delay = 2000;
PriceData priceData = new PriceData();
Price priceObject = new Price();
Timer timer = new Timer();
timer.scheduleAtFixedRate(new PriceTimerTask(priceData, priceObject), delay, period);
}
You cannot refer to non-final variables because Java Language Specification says so. From 8.1.3:
"Any local variable, formal method parameter or exception handler parameter used but not declared in an inner class must be declared final." Whole paragraph.
I can see only part of your code - according to me scheduling modification of local variables is a strange idea. Local variables cease to exist when you leave the function. Maybe static fields of a class would be better?
I just wrote something to handle something along the authors intention.
I found the best thing to do was to let the constructor take all the objects and then in your implemented method use that constructor objects.
However, if you are writing a generic interface class, then you have to pass an Object, or better a list of Objects. This could be done by Object[] or even better, Object ... because it is easier to call.
See my example piece just below.
List<String> lst = new ArrayList<String>();
lst.add("1");
lst.add("2");
SomeAbstractClass p = new SomeAbstractClass (lst, "another parameter", 20, true) {
public void perform( ) {
ArrayList<String> lst = (ArrayList<String>)getArgs()[0];
}
};
public abstract class SomeAbstractClass{
private Object[] args;
public SomeAbstractClass(Object ... args) {
this.args = args;
}
public abstract void perform();
public Object[] getArgs() {
return args;
}
}
Please see this post about Java closures that supports this out of the box:
http://mseifed.blogspot.se/2012/09/closure-implementation-for-java-5-6-and.html
Version 1 supports passing of non-final closures with autocasting:
https://github.com/MSeifeddo/Closure-implementation-for-Java-5-6-and-7/blob/master/org/mo/closure/v1/Closure.java
SortedSet<String> sortedNames = new TreeSet<String>();
// NOTE! Instead of enforcing final, we pass it through the constructor
eachLine(randomFile0, new V1<String>(sortedNames) {
public void call(String line) {
SortedSet<String> sortedNames = castFirst(); // Read contructor arg zero, and auto cast it
sortedNames.add(extractName(line));
}
});
If you want to change a value in a method call within an anonymous class, that "value" is actually a Future. So, if you use Guava, you can write
...
final SettableFuture<Integer> myvalue = SettableFuture<Integer>.create();
...
someclass.run(new Runnable(){
public void run(){
...
myvalue.set(value);
...
}
}
return myvalue.get();
One solution I have noticed isn't mentioned (unless I missed it, if I did please correct me), is the use of a class variable. Ran into this issue attempting to run a new thread within a method: new Thread(){ Do Something }.
Calling doSomething() from the following will work. You do not necessarily have to declare it final, just need to change the scope of the variable so it is not collected before the innerclass. This is unless of course your process is huge and changing the scope might create some sort of conflict. I didn't want to make my variable final as it was in no way a final/constant.
public class Test
{
protected String var1;
protected String var2;
public void doSomething()
{
new Thread()
{
public void run()
{
System.out.println("In Thread variable 1: " + var1);
System.out.println("In Thread variable 2: " + var2);
}
}.start();
}
}
you can just declare the variable outside the outer class. After this, you will be able to edit the variable from within the inner class. I sometimes face similar problems while coding in android so I declare the variable as global and it works for me.
If the variable required to be final, cannot be then you can assign the value of the variable to another variable and make THAT final so you can use it instead.
use ClassName.this.variableName to reference the non-final variable
Can you make lastPrice, priceObject, and price fields of the anonymous inner class?
The main concern is whether a variable inside the anonymous class instance can be resolved at run-time. It is not a must to make a variable final as long as it is guaranteed that the variable is inside the run-time scope. For example, please see the two variables _statusMessage and _statusTextView inside updateStatus() method.
public class WorkerService extends Service {
Worker _worker;
ExecutorService _executorService;
ScheduledExecutorService _scheduledStopService;
TextView _statusTextView;
#Override
public void onCreate() {
_worker = new Worker(this);
_worker.monitorGpsInBackground();
// To get a thread pool service containing merely one thread
_executorService = Executors.newSingleThreadExecutor();
// schedule something to run in the future
_scheduledStopService = Executors.newSingleThreadScheduledExecutor();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
ServiceRunnable runnable = new ServiceRunnable(this, startId);
_executorService.execute(runnable);
// the return value tells what the OS should
// do if this service is killed for resource reasons
// 1. START_STICKY: the OS restarts the service when resources become
// available by passing a null intent to onStartCommand
// 2. START_REDELIVER_INTENT: the OS restarts the service when resources
// become available by passing the last intent that was passed to the
// service before it was killed to onStartCommand
// 3. START_NOT_STICKY: just wait for next call to startService, no
// auto-restart
return Service.START_NOT_STICKY;
}
#Override
public void onDestroy() {
_worker.stopGpsMonitoring();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
class ServiceRunnable implements Runnable {
WorkerService _theService;
int _startId;
String _statusMessage;
public ServiceRunnable(WorkerService theService, int startId) {
_theService = theService;
_startId = startId;
}
#Override
public void run() {
_statusTextView = MyActivity.getActivityStatusView();
// get most recently available location as a latitude /
// longtitude
Location location = _worker.getLocation();
updateStatus("Starting");
// convert lat/lng to a human-readable address
String address = _worker.reverseGeocode(location);
updateStatus("Reverse geocoding");
// Write the location and address out to a file
_worker.save(location, address, "ResponsiveUx.out");
updateStatus("Done");
DelayedStopRequest stopRequest = new DelayedStopRequest(_theService, _startId);
// schedule a stopRequest after 10 seconds
_theService._scheduledStopService.schedule(stopRequest, 10, TimeUnit.SECONDS);
}
void updateStatus(String message) {
_statusMessage = message;
if (_statusTextView != null) {
_statusTextView.post(new Runnable() {
#Override
public void run() {
_statusTextView.setText(_statusMessage);
}
});
}
}
}
what worked for me is just define the variable outside this function of your.
Just before main function declare i.e.
Double price;
public static void main(String []args(){
--------
--------
}
Declare the variable as a static and reference it in the required method using className.variable
Just an another explanation. Consider this example below
public class Outer{
public static void main(String[] args){
Outer o = new Outer();
o.m1();
o=null;
}
public void m1(){
//int x = 10;
class Inner{
Thread t = new Thread(new Runnable(){
public void run(){
for(int i=0;i<10;i++){
try{
Thread.sleep(2000);
}catch(InterruptedException e){
//handle InterruptedException e
}
System.out.println("Thread t running");
}
}
});
}
new Inner().t.start();
System.out.println("m1 Completes");
}
}
Here Output will be
m1 Completes
Thread t running
Thread t running
Thread t running
................
Now method m1() completes and we assign reference variable o to null , Now Outer Class Object is eligible for GC but Inner Class Object is still exist who has (Has-A) relationship with Thread object which is running. Without existing Outer class object there is no chance of existing m1() method and without existing m1() method there is no chance of existing its local variable but if Inner Class Object uses the local variable of m1() method then everything is self explanatory.
To solve this we have to create a copy of local variable and then have to copy then into the heap with Inner class object, what java does for only final variable because they are not actually variable they are like constants(Everything happens at compile time only not at runtime).
To solve the problem above, different languages make different decisions.
for Java, the solution is as what we see in this article.
for C#, the solution is allow side-effects and capture by reference is the only option.
for C++11, the solution is to allow the programmer make the decision. They can choose to capture by value or by reference. If capturing by value, no side-effects would occur because the variable referenced is actually different. If capture by reference, side-effects may occur but the programmer should realize it.
Because it's confusing if the variable isn't final, as the changes to it won't be picked up in the anonymous class.
Just make the variables 'price' and 'lastPrice' final.
-- Edit
Oops, and you'll also need to not assign to them, obviously, in your function. You'll need new local variables. Anyway, I suspect someone has given you a better answer by now.