So I'm trying to declare an integer variable inside an if/else statement, and print it out, outside of it. Something like this:
int x;
int a = 1;
if (a == 1)
{
int x = 5;
}
System.out.println(x);
This is just an example of what I'm trying to do, as I don't have the actual code with me, and i don't want to redo it all over. Although it shouldn't matter really, as the example is exactly what i need, only with different variable values and names (but it's still an integer). At first i just declared and initialised the variable inside the if/else statement, but then I was told I need to declare it outside the statement... So I did that, then initialised it within the statement, and then proceeded to call on it later on. However I'm still getting an error, either it says the variable hasn't been initialised, or if I assign a value to it (x) then update it inside the statement, the error i get is that it has already been declared. Any help would be appreciated, thanks.
Yes. Local variables needs to be initialize before they use. Where as instance variables initialize to default values if you didn't initialize them before use.
If you are curious about the reason? click here to know
Coming back to your question again,
Because consider the below scenario
Follow comments.
int x; // declared with no value
int a = 0;
if (a == 1) // this is false
{
x = 5; // this never executed
}
System.out.println(x); // what you are expecting to print here ?
Hence you need to initialize with a value. For ex : initialize it with zero and change it later on based on a condition
int x=0;
int a = 1;
if (a == 1)
{
x = 5;
}
System.out.println(x);
Simply assign the int x = 0 before your if-statement, then instead of redeclaring x as an integer equal to 5, set x equal to 5 inside your if statement.
The point is that you declared x above. So remove int before x inside the if-statement. Then it works.
int x;
int a = 1;
if (a == 1) {
x = 5;
}
System.out.println(x);
Implicitly an integer is initiated with 0. If you want to be sure just write
int x = 0;
your code here
int x = -1;
int a = 1;
if (a == 1)
{ // here begins inner 'area' for declared variables
x = 5;
}// and here ends
System.out.println(x);
OK, my bad! I wanted him to wonder why and try some other ways of writting it and letting him get 'hit' by IDE errors.
So Mr. Unknown as far as you declare variable 'inside' if statement it is visible only across that statement! So basicly if You want to do something with variable inside if statement, and have results outside of it, You need to declare it outside the statement making it having wider range of accessibility! If You have any questions don't hesitate to ask ;)
P.S. Watch out for re-declaring variable with the same name like You tried to do here, it's nasty bug to find =)
Thank you all for the answers, I realized I made 2 minor mistakes that didnt allow it to work, I (in most attempts) didn't declare a value for x before the if statement, and I had 'int' in front of x inside the if statement, which caused the re-deceleration error. So yea, thank you for the quick answers :)
Related
Hey I can't get processing to run my code due to a NullPointerException on my array value in the println statement.
for (bx=0; bx<=7; bx++) {
for (by=0; by<=4; by++) {
rect(bx*BRICK_WIDTH, by*BRICK_HEIGHT, BRICK_WIDTH, BRICK_HEIGHT);
int[][] a = {{bx}, {by}};
}
println (a[bx][by]);
}
From just the code you posted, I wouldn't expect you to get a NullPointerException. I would expect you to get a The variable "a" does not exist error.
So I'm guessing that you have another a variable at the top of your sketch, like this:
int[][] a;
void draw(){
for (bx=0; bx<=7; bx++) {
for (by=0; by<=4; by++) {
rect(bx*BRICK_WIDTH, by*BRICK_HEIGHT, BRICK_WIDTH, BRICK_HEIGHT);
int[][] a = {{bx}, {by}};
}
println (a[bx][by]);
}
}
Please note that this is why it's so important for you to post a MCVE, so we don't have to guess at what your code is doing.
If this is the case, your problem is caused because the int[][] a = {{bx}, {by}}; line inside the for loop is declaring a different variable with the same name. It's not touching the skethc-level a variable. So the sketch-level a variable still has the default value of null, hence the NullPointerException when you try to use it.
Also note that it doesn't make a ton of sense to assign a to anything inside the for loop. To see why, consider this simpler example:
int x = 0;
for(int i = 0; i < 10; i++){
x = i;
}
println(x);
You'll see that the x variable only "keeps" the last value we assigned to it. The same thing is true of arrays. Maybe you meant to set a particular index of your array?
If you're still having trouble then please post a MCVE. Good luck.
In a method I have this:
int x = 0
if (isA()) {
x = 1;
} else if (isB()) {
x = 2;
}
if (x != 0) {
doLater(() -> showErrorMessage(x)); // compile error here
}
// no more reference to 'x' here
I don't understand why it produces compilation error. The error says that x is not final or effectively-final, so it can't be accessed from the lambda body. There is no modification to x after the doLater call, so the value of x is actually already determined when doLater is called.
I am guessing that the answer to this question is because x is not qualified to be called an effectively-final variable. However, I want to know what the reason is.
Can't the compiler just create a temporary final variable, effectively making the code like:
if (x != 0) {
final int final_x = x;
doLater(() -> showErrorMessage(final_x));
}
and everything still work the same?
Effectively final means that it could have been made final i.e. it never changes. It means that effectively, the variable could be a final one.
The problem is that it doesn't keep track of the last time you changed it, but rather, did you ever change it. Change your if statement to
int x;
if (isA()) {
x = 1;
} else if (isB()) {
x = 2;
} else {
x = 0;
}
or
int x = isA() ? 1 :
isB() ? 2 : 0;
Your x variable would have been effectively final it it was initialized once and not changed again under any circumstances. If you had only:
int x = 0;
doLater(() -> showErrorMessage(x));
then it would have compiled.
However, adding conditions that might change the variable's value
int x = 0;
if (isA()) {
x = 1;
} else if (isB()) {
x = 2;
}
makes the variable being not effectively final and thus the compile error is risen.
Additionally, since this pointer approach you've implemented wouldn't work, you could refactor your code a bit to a simple if-else statement:
if (isA()) {
doLater(() -> showErrorMessage(1));
} else if (isB()) {
doLater(() -> showErrorMessage(2));
}
and completely get rid of x.
Short version, a variable is effectively final if it is assigned exactly once, no matter which code path is executed.
Long version, quoting Java Language Specification 4.12.4. final Variables (emphasis mine):
Certain variables that are not declared final are instead considered effectively final:
A local variable whose declarator has an initializer (§14.4.2) is effectively final if all of the following are true:
It is not declared final.
It never occurs as the left hand side in an assignment expression (§15.26). (Note that the local variable declarator containing the initializer is not an assignment expression.)
It never occurs as the operand of a prefix or postfix increment or decrement operator (§15.14, §15.15).
Now, you can make it effectively final by removing the initializer, because it continues:
A local variable whose declarator lacks an initializer is effectively final if all of the following are true:
It is not declared final.
Whenever it occurs as the left hand side in an assignment expression, it is definitely unassigned and not definitely assigned before the assignment; that is, it is definitely unassigned and not definitely assigned after the right hand side of the assignment expression (§16 (Definite Assignment)).
It never occurs as the operand of a prefix or postfix increment or decrement operator.
When using Eclipse Luna I run into this issue: When I declare a variable outside of the for loop (or another structure), then initialize it within the For loop, upon closing the for loop the value assigned to the variable within the for loop is not carried over.
Perhaps this is how it's supposed to be, but when using Eclipse Juno I don't have this problem.
int sebastian;
for(int i=0;i<8;i++)
{
sebastian = 5*i;
System.out.println(sebastian);
}
I'm not sure what's wrong there, but it SHOULD be carried over. It looks like it carries over, and when I run it, it carries over.
I ran
public static void main(String[] args) {
int sebastian = 0;
for (int i = 0; i < 8; i++) {
sebastian = 5 * i;
System.out.println(sebastian);
}
// this should print the last value a second time
System.out.println(sebastian);
}
and my output was
0
5
10
15
20
25
30
35
35 // this is the carry over that shows up
See rules for 'Definite Assignment' in the Java Language Spec. You can't refer to a local variable before it has a value assigned:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html
Local variables do not have default values. When you write int sebastian; in a method, the variable sebastien does not the value 0, rather it is unassigned. You cannot use the variable until it is "definitely assigned". The rules for definite assignment are complicated. It seems clear that the variable will have been given a value in the loop (because the loop repeats 8 times), but that does not meet the rules for definite assignment.
int sebastian;
for(int i=0;i<8;i++)
{
sebastian = 5*i;
System.out.println(sebastian); // sebastien is definitely assigned here. It was assigned the line before!
}
System.out.println(sebastian); // sebastien is not definitely assigned here.
The easiest way round this to just give the variable a "dummy" value when you declare it:
int sebastien = -1;
Ok so I am new to programming(Don't laugh at me if I ask a question very easy).
A sample of my code is as follows:
public int calcGCF(int mya, int mye, int myf, int myj)
{
x = myj * myf;
y = mye* mya;
while(x != 0 && y != 0)
{
if(x % y == 0)
{
remainder = y;
}
int gcf;
gcf = y;
y = x % y;
x = gcf;
}
}
Ok. So what this code is for is to potentially solve the derivative of any problem that the user inputs. Part of solving the derivative is getting a gcf of 2 numbers and factoring it out. When I try to compile this code, it says that I am missing a return statement. I understand what that is, but when I try to say "return remainder;" it says it may not have been initialized. Can somebody please tell me what I am doing wrong in this code, and help me with what I should put in my return statement? Thank You! By the way this is with java code.
Where are the variables x, y, and remainder declared? I don't see an int remainder; statement anywhere in the code you posted. There's also no return statement in the method, so it will not compile.
Local variables (variables that you declare inside a method) must be initialized with a value before you use them anywhere where you read the value. If you do this, for example:
public int method(int a) {
int value;
if (a > 10) {
value = 99;
}
return value;
}
Then you will get the same error as you are getting, because in case a is not greater than 10, the variable value isn't assigned any value when you reach the return statement - so Java doesn't know what value to return then.
You must make sure that value is assigned a value in any possible case.
As you wish you can return the remainder. Just initialize your remainder to a value. eg: remainder=0;
I understand what that is, but when I try to say "return remainder;" it says it may not have been initialized.
So you simply need to declare, at the top of your code, something like:
remainder = 0;
I would also think about naming your variables a little more appropriately than just myj.
Have a look at this simple Java code:
class A {
public static void main(String[] args) {
final int x;
try {
throw new RuntimeException();
x = 1;
} finally {}
x = 2;
System.out.println("x: " + x);
}
}
I'd expect it to print "x: 2".
A.java:6: unreachable statement
x = 1;
^
A.java:8: variable x might already have been assigned
x = 2;
^
2 errors
It says it wont compile because on line 8, x = 2 might reassign the final variable, but this is false because as it said above, the line x = 1 is unreachable, thus it will assign it for the first time, not reassign.
Why does the compiler give an error stating that "x might have already been assigned" when it knows that x has not been assigned?
It is explained in the JLS chapter 16
[...] Similarly, every blank final variable must be assigned at most
once; it must be definitely unassigned when an assignment to it
occurs.
Such an assignment is defined to occur if and only if either the
simple name of the variable (or, for a field, its simple name
qualified by this) occurs on the left hand side of an assignment
operator.
For every assignment to a blank final variable, the variable must be
definitely unassigned before the assignment, or a compile-time error
occurs.
So, JLS does not seem to care about unreachable code.
And concerning exceptions it says:
An exception parameter V of a catch clause (§14.20) is definitely
assigned (and moreover is not definitely unassigned) before the body
of the catch clause.
so the problem here is that x=1 and x=2 are both definitely assigned as
If a try statement does have a finally block, then these rules also
apply:
V is definitely assigned after the try statement iff at least one of the following is true:
V is definitely assigned after the try block and V is definitely assigned after every catch block in the try statement.
V is definitely assigned after the finally block.
V is definitely unassigned after a try statement iff V is definitely unassigned after the finally block.
The first error is a result of, well, unreachable code. Once you throw the exception, the method is halted, and the next line can never be executed. You can fix the second error by simply removing the final modifier from x. But I must ask, why are you writing a program whose only purpose is to throw a RuntimeException?
The java compiler can't look at things the same way we do as humans. It doesn't see cause and effect, only what is in error. And in this case it may be a good thing, because even if you fix one of the errors, the other will persist.
It's probably a language definition issue. One area of the spec prohibits reassignment if it might have already been assigned. A different area discusses unreachable code.
The combination of the two is probably never really addressed.
Could you perhaps supply something that is a bit more representative of what you are really trying to accomplish?
Looks like you are learning Java. The first error is because the compiler can see that execution of a block cannot continue after you throw an exception: control will jump to wherever the exception is caught. Other posters have explained the second error.
I've seen other cases that are less straightforward, for example something like:
final int x;
boolean b = ...;
if(b) {
x = 1;
}
...
if(!b) {
x = 2;
}
The easiest solution is to assign to a temporary non-final variable, then copy it to the final variable:
final int x;
int _x = 0;
boolean b = ...;
if(b) {
_x = 1;
}
...
if(!b) {
_x = 2;
}
x = _x;