Local method variable, unrecognized - java

I have a method public int bar(), where i have declared an int total(in the method body ofc). So this should be a simpel local variable, the thing is that eclipse complain about
Description Resource Path Location Type
The local variable total may not have been initialized Repository.java /proj_individual/src/repo line 35 Java Problem
general example :
public int foo(){
int total;
for(... : ...){
total += 1; // complains
}
return total;// complains
}
and my exact code:
public int getLocatars(){
int total;
for ( Map.Entry<Apartment, List<Expense>> entry : dic.entrySet() ) {
if(entry.getKey().isDebt()){
total += entry.getKey().getNrProple();
}
}
return total;
}
I have no idea what I may have done wrong, so any idea is helpful, thank you.

Your variable isn't definitely assigned a value, so you can't read it.
Imagine if your entry set is empty, or has no debt entries... what value would you want to return?
More than that, even if it does get into the inner-most part of your loop, what initial value would you expect to be added to?
Unlike static and instance fields, local variables don't have default values: you have to assign values to them before you read them. I suspect you just want:
int total = 0;

Change it from:
int total;
to:
int total = 0;
For better understanding, see: differences between declaration and initialization.

Related

Why does javac allow fields to be defined after methods that use them in a class?

I have noticed that when you execute a statement like sum=a+b;
we need the three fields initialized prior to using them in this operation
ie
int a=1
int b=1;
int sum=0;
sum=a+b;
.
My understanding is, this is because javac works like an interpreter and reads line by line.
But when it comes to methods where we call and pass values to fields inside a class we can define the fields after method declaration.
public class Dog extends Animal{
public Dog(String name, int weight, int teeth, String coat) {
super(name, true, true, weight);
this.tail=true;
this.eyes=2;
this.teeth=teeth;
this.coat=coat;
}
private int eyes;
private boolean tail;
private int teeth;
private String coat;}
The parameters eyes, tail, teeth, and coat have been defined after they were used to pass values to the constructor.
How does javac understand that there is a variable after the method.
Is this allowed because we can only define fields and not do any operations on them in a class definition?
Javac is Java Compiler Compiles your Java code into Bytecode
JVM is Java Virtual Machine Runs/ Interprets/ translates Bytecode into Native Machine Code
This error occurs only with local variables because the compiler does not set the default value for the local variables. In the case of instance variables, the compiler sets default values, for example, 0 for integer, null for string, etc.
In the above case if you don't set values in the constructor still your instance variables will be initialized by default values.
private int eyes = 0;
private boolean tail = false;
private int teeth = 0;
private String coat = null;
But same is not true for local variables a, b or sum.
sum can be uninitialized because you are assigning the values to the sum before using it. That is the statement sum = a+b will assign value and before you use it somewhere else may be like sum2 = sum, its assured that sum has a value.
A local variable declaration (and eventual initialization) is executed together with the block it is in, and being accessed from;
an instance field declaration (and initialization) is executed when the instance is created, before the methods are executed 1.
On the other side this is not allowed:
public class Dog extends Animal {
private int total = eyes + teeth; // ERROR!
private int eyes = 2;
private int teeth = 24;
}
above code does not compile - that is intentional!
while this is valid:
public class Dog extends Animal {
private int eyes = 2;
private int teeth = 24;
private int total = eyes + teeth; // OK
}
Why ...? Short answer: it is specified that way, see Java Language Specification (JLS) - Scope of a Declaration:
The scope of a declaration of a member m declared in ... a class or interface C (§8.2, §9.2) is the entire body of C, ...
The scope of a local variable declared in a block by a local variable declaration statement (§14.4.2) is the rest of the block,...
One reasons for that is to avoid cyclic references as mentioned in the JLS, see examples on link below 1. Also explained in this answer by Hoopje.
1 - exception are references to fields in initializers, see Restrictions on Field References in Initializers
This has nothing to do with the difference between an interpreter and a compiler. It is just a rule added to language to prevent two fields to refer to each other in their initialization code. For example, what would be the initial values of the fields in the following class?
class A {
int a = b * b;
int b = a + 1;
}
Of course, the Java designers could have decided to allow forward references, and only generate an error when such cycles are detected. But they decided otherwise, and I think that that was the right decision.
There is no reason to forbid forward references to fields from within a method, because when the method is executed, the class is initialized already. Even constructors run after the fields' initializers have been evaluated.

'illegal start of expression' but outside of main

Please bear with me I'm very new to this. I am going through some tutorials and I am getting this error
GradeAnalyzer.java:51: error: illegal start of expression
myAnalyzer.getAverage(ArrayList<Integer>);
I have found so many threads saying take the method outside the main, however unless I am really stupid I'm pretty sure mine is outside of the main already. All advice regarding the matter is welcome (also feel free to heavily criticise the rest of my code).
import java.util.ArrayList;
public class GradeAnalyzer {
public GradeAnalyzer() {
}
public int getAverage(ArrayList<Integer> grades) {
;
if (grades.size() < 1) {
System.out.println("Unfortunately the Array you are using is empty");
return 0;
} else {
int sum = 0;
for (Integer grade: grades) {
System.out.println(grade);
sum = sum + grade;
}
int average = sum / grades.size();
System.out.println("Average =" + average);
return average;
}
}
public static void main(String[] args) {
ArrayList<Integer> myClassroom = new ArrayList<Integer>();
myClassroom.add(98);
myClassroom.add(92);
myClassroom.add(88);
myClassroom.add(75);
myClassroom.add(61);
myClassroom.add(89);
myClassroom.add(95);
}
public int myAnalyzer(ArrayList<Integer> myClassroom) {
GradeAnalyzer myAnalyzer = new GradeAnalyzer();
myAnalyzer.getAverage(ArrayList<Integer>);
}
}
This is the culprit:
myAnalyzer.getAverage(ArrayList<Integer>);
You've provided a type where an expression is expected. You probably wanted to pass in the myClassroom argument:
myAnalyzer.getAverage(myClassroom);
Other notes:
You probably want to get rid of the stray ; at the top of getAverage as well. I don't think it's a syntax error, but it's pointless.
I don't see a call to myAnalyzer (the method) anywhere.
myAnalyzer is a very strange name for a method.
It's best not to declare a local variable (myAnalyzer) inside a method with the same name (myAnalyzer) (although it's valid).
In general, try to keep variable types to interfaces rather than concrete types, so:
List<Integer> myClassroom = new ArrayList<Integer>();
...rather than using ArrayList<Integer> on the variable declaration.
If using ArrayList (which does, after all, allocate and maintain an array), where possible tell it the initial capacity to use so you ensure that you're not doing unnecessary array re-allocations as you add things.
sum += grade; is the idiomatic way to write sum = sum + grade; (although the latter works).
myAnalyzer.getAverage(ArrayList<Integer>);
is not a valid method call. You should pass an instance whose type is ArrayList<Integer>.
For example, if you call it from your main, you can write :
myAnalyzer.getAverage(myClassroom);
Or, if you don't want to put this method in your main, move the myClassroom ArrayList declaration and initialization to myAnalyzer method.

error: cannot assign a value to final variable (int)

Ok I'm sure this is simple, but I'm having issues and my mind is blank. =(
I know 'final' makes it so the variable can't change but that's pretty much all I can figure out about it right now.
And the code...
If I take out the 'final' the error comes up as "error: missing return statement
}" for the first two methods.
EDIT: Thank you all for the help, surprising how fast I got help!
So I just took out 'final' and added 'void' to the first two methods. I'm sure it'll take some time to fully understand everything, but it definitely helps.
There is a part two and here is the part that I have no clue on what to do...
The second part you just have to test this first program. Am I supposed to make a separate file with the same code?
If anyone can help great, but if not thats fine I'll work on it later.
You declare your function as
public static int removeOneFromRoom (int number)
{
totalNumber = totalNumber-number;
}
The emphasis here is the public static int, telling the compiler that your function is supposed to return an integer. You do however not return anything in that function body, so the compiler complains rightfully. Either return something, or declare the return value as void.
Maybe you're missing the return statement for the first two methods. Or you may want to change the return type to void if you don't need to return anything.
Doing these will remove your error but it might differ from what you need.
public static void addOneToRoom(int number)
{
numberInRoom = numberInRoom+number;
}
public static void removeOneFromRoom (int number)
{
totalNumber = totalNumber-number;
}
Hope this helps.
A variable declared with static and final keywords behaves like a constant. But what does that mean ?
It means you can't change their values. In simpler terms if variable is a primitive then you can't change its value but if its a reference variable then you can't change the reference to some other address.
So in your code, declaring numberInRoom and totalNumber variables as static and final is wrong
public static int numberInRoom=3;
public static int totalNumber=30;
public static int addOneToRoom(int number)
{
numberInRoom = numberInRoom+number;
}
public static int removeOneFromRoom (int number)
{
totalNumber = totalNumber-number;
}
Are you sure that you want these variables to be declared as static because such variables shall be shared by all instances of the concerned class. Please have a look at what does declaring variables as static and final means

How are local variables in method counted java bytecode

I have been learning about java byte-code recently, and i have been understanding most of it, but i am confused about how the local variable count for example is counted. I thought it would just be the total of the local variables, but this code generates 1 local variable when looking through the bytecode
public int testFail()
{
return 1;
}
But i thought it should be zero local variables because no local variable are defined.
Additionally this method also generates one local variable but it has more local variables than the previous example.
Finally this method
public static int testFail(int a, int b)
{
return a+b;
}
gnerates two local variable in the bytecode.
public static int testFail(int a)
{
return a;
}
Non-static methods use a local variable slot for this. Another complication is that longs and doubles count as 2 each. Also, depending on your compiler and settings, you may not see a one-to-one mapping between local variables in the source code and local variables in the byte code. For example, if debug information is left out, the compiler may eliminate unnecessary local variables.
Edit:
I just remembered: compilers may also re-use local variable slots. For example, given this code:
public static void test() {
for(int i = 0; i < 100; i++) {
...
}
for(int j = 0; j < 100; j++) {
}
}
the same slot can be used for i and j because their scopes don't overlap.
The reason the first one has a local variable is because it is a nonstatic method, so there is an implicit this parameter.

GWT. Create primitive (no- referencable) Integer variable

In my class, I have field int count. I want to create a new variable according to value of count variable, like this: int a = new Integer(count). But when I update count variable: count++, then variable a also gets updated. So how to create non-referencing int variable?
You can't do this with Java. Your closest bet would be to create an enclosing class with a single int, and refer to that instead:
class MutableInteger {
public int value;
}
Then, later:
MutableInteger a = new MutableInteger();
a.value = 5;
MutableInteger b = a;
b.value++;
a.value++;
//since a.value is the same primitive as b.value, they are both 7
But: this breaks a bunch of commonly-accepted best practices in Java. You might look for an alternative way to solve whatever your real problem is.
The situation you've described can't really happen.
Try this code:
int count = 15;
int a = new Integer(count);
count++;
Window.alert("a is "+ a + " and count is " + count);
count is updated and a isn't. So it means you have error somewhere else.
Try the following:
int a = count + 0;
Your problem is somewhat misguided. Here is why:
In Java, the primitive values, when copied, their references are not copied.
look to your code and seek where you are doing an additional step.
The constructor of Integer uses this:
this.integer = integer;

Categories