import java.util.Scanner;
public class finnTall {
public static void main(String[]args){
int antallTall;
int antallLest;
double nesteTall;
double minsteVerdi;
double nestMinsteVerdi;
Scanner tast = new Scanner(System.in);
System.out.println("Hvor mange tall?");
antallTall = tast.nextInt();
tast.nextLine();
antallLest= 1;
System.out.println("Skriv første tall: ");
minsteVerdi = tast.nextDouble();
tast.nextLine();
for(antallLest=1;antallTall>antallLest;antallLest++){
System.out.printf("Skriv %d. tall: ",antallLest+1);
nesteTall = tast.nextDouble();
tast.nextLine();
if(nesteTall>minsteVerdi)
nestMinsteVerdi=nesteTall;
if(nesteTall<minsteVerdi)
nesteTall = minsteVerdi;
if(nesteTall>minsteVerdi && nesteTall<nestMinsteVerdi)
nestMinsteVerdi = nesteTall;
}
System.out.printf("Minste verdien av tallene du har oppgitt er: %f\n",minsteVerdi);
System.out.printf("Nest minste verdi av tallene du har oppgitt er: %f\n",nestMinsteVerdi);
tast.close();
}
}
It's a program supposed to calculate the lowest and second lowest number that the user provides.
For some reason, it says that the local variable nestMinsteVerdi is not initialized, and I can't seem to figure out why or where the fault is. I have been struggling with this for a good 2 hours.
Thanks in advance.
In Java, a local variable needs to have a definitely assigned value before its value is accessed.
You declare your local variable without assigning it a value. This is okay in Java, because the compiler will ensure that you give it a value before using it.
double nestMinsteVerdi;
Then set it if a condition is true:
if(nesteTall>minsteVerdi)
nestMinsteVerdi=nesteTall;
Then access it in the conditional of an if statement. But if the condition above were false, the value of nestMinisteVerdi would not yet be assigned.
if(nesteTall>minsteVerdi && nesteTall<nestMinsteVerdi)
nestMinsteVerdi = nesteTall;
Since there's at least one way for the code to execute in which no value is assigned, the compiler complains. This is a good thing. Accidentally uninitialized variables can be a frequent source of defects.
From the Java Language Specification, Chapter 16: Definite Assignment:
The idea behind definite assignment is that an assignment to the local variable or blank final field must occur on every possible execution path to the access.
Andy Thomas's answer is correct. You do not assign a value to the variable.
double nestMinsteVerdi;
The compiler will not allow you to run because the only assignment is within a conditional that could conceivably fail, and if it were to fail, the variable would not be assigned a value. Since code can't be compared to a variable with no value, this would break execution, so the compiler will not allow it.
Related
I am a little bit confused about the following piece of code:
public class Test{
int x = giveH();
int h = 29;
public int giveH(){
return h;
}
public static void main(String args[])
{
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
The output here is 0 29, but I thought that this has to be a compiler error, because the variable h should have not been initialized when it comes to the method giveH(). So, does the compilation go through the lines from top to bottom? Why is this working? Why is the value of x 0 and not 29?
The default value of int is 0 (see here). Because you initialize x before h, giveH will return the default value for a int (eg 0).
If you switch the order like this
int h = 29;
int x = giveH();
the output will be
29 29
Compilation in Java doesn't need the method to be declared before it is used. The Java tutorial goes into a bit more detail on initialization.
Here's a way to think about it: the compiler will make a note to look for a method called giveH somewhere in scope, and it will only error if it leaves the scope and doesn't find it. Once it gets to the giveH declaration then the note is resolved and everyone is happy.
Also, the variable initialization for instance variables in Java is moved to the beginning of the constructor. You can think of the lines above being split into two parts, with the declaration for x and h above, and the assignment inside the constructor.
The order of declaration does matter in this case. When the variable x is initialized, h has the default value of 0, so giveH() will return that default value. After that, the variable h is given the value 29.
You can also look at the Java Language Specification sections on Field Initialization and Forward References During Field Initialization.
#Maloubobola has provided the correct answer, but since you don't seem to fully understand yet, let me try to elaborate.
When Test is created, it runs the variable initialization (x = giveH(), h= 29) once. Your misunderstanding may be that variable x is always determined by giveH(), whereas it only determines it's value when x is initialized.
That's why the order of the statements is crucial here; x is initialized before h, and therefore h is 0 when giveH() is called at x's initialization.
It's bad practice to use a method in the field initializer. You can fix this by making h final. Then it will be initialized when the class is loaded.
import java.util.ArrayList;
public class Test {
int x = giveH();
final int h=29;
final public int giveH(){
return h;
}
public static void main(String args[]) {
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
If we do not initialize the value for non static variables like x in this program JVM will provide default value zero for class level non static variables.
Once declared, all the array elements store their default values.
Elements in an array that store objects default to null.
Elements of an array that store primitive data types store:
0 for integer types (byte, short, int,long);
0.0 for decimal types (float and double);
false for boolean;
\u0000 for char data.
Actauls values will come only when we give initialize them
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 :)
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;
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;
I understand how to pass a variable to another method and I even learned how to do multiple variables to a single method. My problem is I am trying to make a switch statement, when the user inputs a symptom for digoxin(medication for heart) in the statement I want to award him 10 points store it in a variable, and when the user enters another symptom I want to store that in variable as well in a new method. My problem is that after I send the variable to my method and continue with the program it inevitably resets it to zero, and thus dooming my efforts.
Code:
switch(input5) {
case "Vomiting":
score = 0;
num = 0;
score = num + 10;
getMethod(score,0);
System.out.println(getMethod(num));
JOptionPane.showMessageDialog (null,"you're correct") ;
break;
case "Dizziness":
JOptionPane.showMessageDialog (null,"you're correct") ;
score = num + 10;
getMethod(0,score);
break;
case "Confusion":
JOptionPane.showMessageDialog (null,"you're correct");
break;
case "Vision":
JOptionPane.showMessageDialog (null,"you're correct");
break;
default :
JOptionPane.showMessageDialog (null,"you're Wrong");
break;
}
...
static int getMethod(int total) {
int amount = total;
int amount2 = total2;
int result = amount + amount2;
return result;
}
The problem with this question is that it is so poorly phrased that it is difficult to understand what you actually think is happening. Unless we understand that, it is hard to answer it properly. So I'm just going to point out some things that appear to be errors in your thinking.
Variables don't "reset" in Java. In this case that the problem is that your getMethod method doesn't update score.
If a method returns a value, and that value isn't assigned to something then it is thrown away. In your case you are not assigning the value returned by getMethod in the places that you are calling it.
In Java, arguments are passed to methods "by value". The upshot is that something like this won't work:
int test = 1;
increment(test, 2);
public void increment(int value, int by) {
// FAIL - the local copy of "value" is incremented, but the
// the original "test" variable is not touched.
value = value + by;
}
Note that this has nothing to do with the names of the variable. The issue is that the variable inside the method is not "connected" in any way to the variable used at the call site. The method updates the former ... and not the latter.
A couple things that need to be said about your code:
It is important to indent your code consistently. There are style guides that tell you what to do. (We've reindented your code in a way that would be acceptable under most style guidelines.)
It is important to use sensible and informative names for things like methods, variables and classes. This helps readers understand what the code author intended the code to do / mean. In your case "getMethod" tells the reader nothing about what the method is supposed to do.
Methods should also have javadoc comments that state what they are supposed to do, what the arguments and results mean, and so on.
i think the issue here is that every time you enter something and enter your switch statement, it resets the score to 0.
switch(input5){
case "Vomiting":
score = 0;
I think you need to set score to 0 before the first input, and not reset it every time you put in vomiting. I can't exactly follow your code, please link the full class.
Try this:
score = getMethod(score, 0);
In java, primitives are "passed by value". The value, not the variable, is passed to the method. Changing the value within the method does nothing to the variable that was used to call the method.
Create a static global variable to maintain or persist the score. This will allow you to make subsequent calls to your method and still keep track of an accurate score.
So, create a global variable public static int score = 0;. Inside of your method you can get rid of the score variable initialization to zero score = 0; since you will use the global score variable.