Reputation: 1989
public class test {
public static void main(String[] args) throws Exception {
final int num = 111;
new Thread() {
@Override
public void run() {
num = 222;
}
}.start();
}
}
I want to change the value of num
however I can only do that if I set it to final
which would not let me modify this. In other languages such as C we can use pointers but Java cannot?
Upvotes: 2
Views: 2410
Reputation: 2768
Well, you can access it if you declare variable outside the function. Like this:
public class test {
private static int num = 111;
public static void main(String[] args) throws Exception {
new Thread() {
@Override
public void run() {
num = 222;
}
}.start();
}
}
Upvotes: 2
Reputation: 13196
main
is a method. As with other programming languages, when a method returns, all of the variables declared in its body go out of scope, and accessing them has undefined behavior. Under some circumstances, the memory location where they used to be will no longer be valid.
Obviously this is a problem. If you try to change num
after main
has returned, you might overwrite a portion of the stack that doesn't belong to num
anymore. Java's response to this difficult situation is to introduce restrictions on how you can share variables: they must be final. Java can then safely locate them in such a way that reading them will produce consistent results even after the function has returned.
The C equivalent to this problem is storing and using the address of a local variable outside of its scope, something that all C programmers are taught to never do.
To get around it, declare num
as a member of test
, create an instance, and pass that to it. This removes the dependancy on a local variable, and thus removes the final
restriction.
public class test
{
int num = 111;
public static void main(String[] args) throws Exception
{
test t = new test();
(new Thread(t) {
test mytest;
Thread(test t)
{
mytest = t;
}
@Override
public void run() {
mytest.num = 222;
}
}).start();
}
}
Upvotes: 2
Reputation: 66657
You are creating new Thread() {
class as inner class. You can't access outer class variables without declaring them as final.
You can't change final variable references.
There are two ways you can do this,
1) Make num as static
2) Wrap num inside an object (You can update state of the object even though you define reference as final).
NOTE: Both are not thread safe.
Upvotes: 1
Reputation: 382374
Java has neither closure nor pointers.
A solution would be to make the num static in the class :
public class test {
static int num = 111;
public static void main(String[] args) throws Exception {
new Thread() {
@Override
public void run() {
num = 222;
}
}.start();
}
}
Another solution would be to use an object like AtomicInteger. You can't change the value of the variable but you can change the content of the value :
public class test {
public static void main(String[] args) throws Exception {
final AtomicInteger num = new AtomicInteger(111);
new Thread() {
@Override
public void run() {
num.set(222);
}
}.start();
}
}
Upvotes: 4
Reputation: 6450
Yep you can't win here! You need to set it final to be able to access it, but then you will not be able to modify it. You'll need to look at a different approach.
Upvotes: -1