can anyone tell me why I get this error?
illegal start of expression private int confirm;
and also
illegal start of expression private File soundFile3 = new File("merge.wav");
If I remove the word "private" the compiler doesn't show any errors.
The code is part of a public method.
Why?
Thank you.
the code is:
private int confirm;
confirm = JOptionPane.showConfirmDialog(this,
"Different sample size....",
"JOin", JOptionPane.OK_CANCEL_OPTION);
if (confirm != JOptionPane.OK_OPTION) {
return;
}
private File soundFile3 = new File("merge.wav");
private keyword cannot be used inside methods. it can be used to declare class fields or methods:
class Foo {
private int num; //private can be specified here
public void foo() {
int s = 1;
int k = num+s; //no private here
}
}
I guess you cannot put an access modifies except final in a method. It makes no sense to have a private modifier for a method level variable. As methods variables are created in their separate stack and destroyed when the scope is lost.
You should use access modifiers only on class members, not local variables.
Local variables are always visible only in the scope of the block where they were declared. So, if you declare a variable in your method, that variable will be visible only within that method. So, no need to use private there. I mean, no need even if you could.
Related
I have an array of seats, and the array has two strings(selected and empty). On mouse click, I want to traverse the array and find the selected seat. When I press the button it says:
The final local variable seatno cannot be assigned, since it is defined in an enclosing type.
JButton btnContinue = new JButton("Next");
btnContinue.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent arg0) {
for(int x=0;x<17;x++){
if(anArray[x]=="selected"){
seatno = anArray[x];
}
}
data page=new data(newfrom,newto,newtime,date2,seatno);
page.setVisible(true);
setVisible(false);
}
});
btnContinue.setBounds(358, 227, 62, 23);
contentPane.add(btnContinue);
The point is that method-local variables from the enclosing type are actually copied to instances of anonymous classes (this is because of activation frame issues, but I won't go further into detail as this is not really relevant to the question), which is why they need to be final, because the variable in the nested type instance is not the same anymore.
So, here is the first example:
void foo() {
int a = 3;
new Runnable() {
#Override
public void run() {
a += 3;
}
};
}
This does not compile, because you cannot reference a non-final variable in an anonymous class' method. When you add a final modifier to the declaration of a, the value of a would be copied into the created instance of the anonymous class you have defined. However, you will not be allowed to change the value of a, because the changes would not be visible to the method where a was declared.
However, anonymous classes are not static, that is, they have a reference to the enclosing instance (unless the method where they are declared is static) which you can use to modify variables of the enclosing instance:
int a = 3;
void foo() {
new Runnable() {
#Override
public void run() {
a += 3;
}
};
}
This example does compile and it would increase a by 3 every time the run() method of the anonymous class' instance is called. (In this example it is never called, but it is just an example.)
So, to summarize, you need to convert the variable seatno from a method-local variable to an instance variable of the enclosing type. Or, if it is yet, you need to remove the final modifier as final variables can only be assigned once.
Update: In Java 8, the concept of effectively final variables is introduced (see Java Language Specification). However, in the first example of this post, the variable a is assigned multiple times, which prevents it from being effectively final. This means that this example still does not compile with Java 8. (The compile error is "Local variable a defined in an enclosing scope must be final or effectively final")
A final variable cannot change it's value (it's similar to const from C/C++).
You probably want to make it a field in a class (without the final keyword of course), not a local variable inside a function.
Instead of defining a class member variable you can also use a mutable int to achieve the same.
void foo() {
final MutableInt a = new MutableInt(3);
new Runnable() {
#Override
public void run() {
a.add(3);
}
};
}
Since MutableInt is not primitive type (hence passed by reference) and can be reassigned this works.
I recently faced similar problem. In my case it was easier to create final array (or collection) and to add variable, that I wanted to change inside anonymous class, to this array, as below.
int a = 3;
final int[] array = new int[1];
array[0] = a;
new Runnable() {
#Override
public void run() {
array[0] += 3;
}
};
Without knowing the declaration of seatno, I'd suggest to introduce a new variable in the mouseClicked() method that is not final and does the same job as seatno currently does, as the variable seems only to be used inside that method.
By the way: Capitalize your class names (data should be Data). Will look much more clear.
Make sure your variable doesn't have the final modifier.
//final, can be set only when the object is created.
private final String seatno;
//no final modifier, the value can be set every time you "want"
private String seatno;
Also, to compare Strings you should use equals:
if(anArray[x].equals("selected"))
This is more of a hypothetical question but if I have some final called A and another final B that are both ints, I can't do this:
private final int A = B/2, B = (some kind of other derived number);
I am just wondering why. Any help would be awesome. NetBeans popped up an error on this and I just want to know why it is a problem.
PS-The error that popped up said "illegal forward reference".
You are accessing variable B before you declare it. That's the reason for "illegal forward reference".
Define variable B before A
private final int B = (some kind of other derived number), A = B/2;
Pretend you're the compiler:
private final int ok. Mr user wants a "const" int
A the variable is called A
= ...here comes the value
B/2 HUH? WHAT THE HELL IS B? NO ONE TOLD ME ANYTHING ABOUT B. STUFF YOU USER. I'M OUT OF HERE...
The existing answers don't answer the underlying question:
Why can I use methods that are defined later in my source file, but does the same with variables cause a forward reference error message?
The answer is found in the JLS, more specifically JLS $12.4.1
The static initializers and class variable initializers are executed in textual order, and may not refer to class variables declared in the class whose declarations appear textually after the use, even though these class variables are in scope (§8.3.2.3). This restriction is designed to detect, at compile time, most circular or otherwise malformed initializations.
This question was answered here. Basically it means that you are trying to use a variable that is not initiated.
Initialize B first, then use it to initialize A
private final int B = ?, A = B/2;
illegal forward reference in java
Your code isn't failing because A and B are final. It's failing because B isn't declared/initialized yet. If you declare it first, you'll be able to use them just fine.
For example,
private final int C = 5;
private final int B = C/3;
private final int A = B/2;
This is fine because B is declared first :)
"final" just means that you can't change the variable. So something like this won't work
private final static int C = 5;
private final static int B = C/3;
private final static int A = B/2;
public static void main (String[] args) {
A = 5;
}
because now we're trying to modify A which is "final"
In Java, you don't have declare a method physically before you use it. The same thing doesn't apply for variables.
Why is this the case? Is it just for "legacy" reason (ie., the Java's creators didn't feel like doing it), or is it just not possible?
Eg.,
public class Test
{
// It is OK for meth1 to invoke meth2
public void meth1() { meth2(); }
public void meth2() { }
// But why is it NOT ok for field1 to reference field2
private int field1 = field2;
private int field2 = 3;
}
If I wanted my Java compiler to support this kind of forward-reference, what is the general idea as to how to do it?
I understand there'd be issue about circular depencies, which we'd need to be careful about. But other than that, I really don't see why it should not be possible.
[Edit]Ok, here's my initial thought as to how to do this.
While analysing the code, the compiler would build a graph of dependencies for the variables in the given scope. And if it sees a loop (ie., int a = b; int b = a), then it would throw an error. If there is no loops, then there must be some optimal way to re-arrange the statements (behind the scence) such that a field will only reference fields declared before it, and so it shouuld try to figure out the order. I haven't worked out the exact algorithm, but I think it is possible. Unless someone can scientifically prove me wrong.
Recap the question:
Say I'm trying to build my own dialect of Java, which supports this sort of scoping. My main question is, could you give me some ideas as to how to do this
Thanks
According to the JLS, Section 12.4.1, initialization of class variables proceeds from top to bottom, in "textual order":
The static initializers and class variable initializers are executed in textual order, and may not refer to class variables declared in the class whose declarations appear textually after the use, even though these class variables are in scope (§8.3.2.3). This restriction is designed to detect, at compile time, most circular or otherwise malformed initializations.
So, if you make your own compiler to recognize forward class variable declarations, then it is violating the Java Language Specification.
I will give you a simple piece of code:
public class Test
{
private int foo = bar;
private int bar = foo;
}
What would you expect this to do?
I presume that designers of Java has done it so because assignment of values to instance variables must be executed in some order. In the case of Java, they are executed downwards (from up to bottom).
EDIT
What about this?
public class Test {
private int foo = quu++;
private int bar = quu++;
private int quu = 1;
}
What values would foo and bar have? Which quu++ statement would be executed first?
My point is, Java designers must have thought that it is counter intuitive to do it as you did describe in your question, i.e. unordered execution with compile time code analysis.
FINAL EDIT
Let's complicate things:
class Test {
private James james = new James(anInt);
private Jesse jesse = new Jesse(anInt);
private IntWrapper anInt = new IntWrapper();
}
class James {
public James(IntWrapper anInt) {
if(--anInt.value != 0) {
new Jesse(anInt);
}
else {
anInt.isJames = true;
}
}
}
class Jesse {
public Jesse(IntWrapper anInt) {
if(--anInt.value != 0) {
new James(anInt);
}
else {
anInt.isJames = false;
}
}
}
class IntWrapper {
public int value = 99;
public boolean isJames;
}
I am not sure what it proves regarding your question because I am not sure about your point.
There is no circular dependency here but value of an instance variable of IntWrapper, isJames, depends on the execution order and it might be difficult to detect this kind of stuff with a lexical/semantic analyzer.
How will field1 know value of field2 before it has been defined and assigned a value?
It has to do with the order of initialization. Fields are initialized top to bottom. In your example, when field1 tries to reference field2 in the initializer, the latter is yet to be initialized itself.
The rule about forward references is aimed at catching the most obvious cases of this problem. It does not catch all; for example, you can still do:
private int field1 = getField2();
private int field2 = 3;
private int getField2() { return field2; }
and get field1 intialized to zero where you might be expecting 3.
I have a class with several methods. Now I would like to define a helper method that should be only visible to method A, like good old "sub-functions" .
public class MyClass {
public methodA() {
int visibleVariable=10;
int result;
//here somehow declare the helperMethod which can access the visibleVariable and just
//adds the passed in parameter
result = helperMethod(1);
result = helperMethod(2);
}
}
The helperMethod is only used by MethodA and should access MethodA's declared variables - avoiding passing in explicitly many parameters which are already declared within methodA.
Is that possible?
EDIT:
The helper mehod is just used to avoid repeating some 20 lines of code which differ in only 1 place. And this 1 place could easily be parameterized while all the other variables in methodA remain unchanged in these 2 cases
Well you could declare a local class and put the method in there:
public class Test {
public static void main(String[] args) {
final int x = 10;
class Local {
int addToX(int value) {
return x + value;
}
}
Local local = new Local();
int result1 = local.addToX(1);
int result2 = local.addToX(2);
System.out.println(result1);
System.out.println(result2);
}
}
But that would be a very unusual code. Usually this suggests that you need to take a step back and look at your design again. Do you actually have a different type that you should be creating?
(If another type (or interface) already provided the right signature, you could use an anonymous inner class instead. That wouldn't be much better...)
Given the variables you declare at the top of your method can be marked as final (meaning they don't change after being initialized) You can define your helper method inside a helper class like below. All the variables at the top could be passed via the constructor.
public class HelperClass() {
private final int value1;
private final int value2;
public HelperClass(int value1, int value2) {
this.value1 = value1;
this.value2 = value2;
}
public int helperMethod(int valuex) {
int result = -1;
// do calculation
return result;
}
}
you can create an instance of HelperClass and use it inside the method
It is not possible. It is also not good design. Violating the rules of variable scope is a sure-fire way to make your code buggy, unreadable and unreliable. If you really have so many related variables, consider putting them into their own class and giving a method to that class.
If what you mean is more akin to a lambda expression, then no, this is not possible in Java at this time (but hopefully in Java 8).
No, it is not possible.
I would advise you create a private method in your class that does the work. As you are author of the code, you are in control of which other methods access the private method. Moreover, private methods will not be accessible from the outside.
In my experience, methods should not declare a load of variables. If they do, there is a good chance that your design is flawed. Think about constants and if you couldn't declare some of those as private final variables in your class. Alternatively, thinking OO, you could be missing an object to carry those variables and offer you some functionality related to the processing of those variables.
methodA() is not a method, it's missing a return type.
You can't access variables declared in a method from another method directly.
You either has to pass them as arguments or declare methodA in its own class together with the helpermethods.
This is probably the best way to do it:
public class MyClass {
public void methodA() {
int visibleVariable=10;
int result;
result = helperMethod(1, visibleVariable);
result = helperMethod(2, visibleVariable);
}
public int helperMethod(int index, int visibleVariable) {
// do something with visibleVariable
return 0;
}
}
$ javac InitInt.java
InitInt.java:7: variable right might not have been initialized
InitInt(){}
^
1 error
$ cat InitInt.java
import java.util.*;
import java.io.*;
public class InitInt {
private final int right;
// Design Problem?
// I feel the initialization problem is just due to bad style.
InitInt(){}
InitInt{
// Still the error, "may not be initialized"
// How to initialise it?
if(snippetBuilder.length()>(charwisePos+25)){
right=charwisePos+25;
}else{
right=snippetBuilder.length()-1;
}
}
public static void main(String[] args) {
InitInt test = new InitInt();
System.out.println(test.getRight());
}
public int getRight(){return right;}
}
Partial Solutions and Suggestions
use "this" to access methods in the class, instead of creating empty constructor
change final to non-final
with final field value: initialize all final values in every constructor
remove the empty constructor, keep your code simple and clean
You mean define, not initialize. The problem you're having (after that pretty radical edit) is you're defining a constructor that doesn't initialize a final variable, which Java doesn't allow -- all finals need to be initialized by the time the instance is finished constructing. Either initialize it in your constructor, or make it non-final
Yeah, the problem is that one of your constructors doesn't initialize the final field. In Java final non-static fields have to be initialized at the declaration time, in an initialization block, OR in EVERY constructor! The default constructor in your example doesn't do that.
Remember as well that implementing an empty default constructor makes sense only if you want to use inheritance features. If you don't provide a default constructor, but you will some other one Java won't make a hidden default constructor for you, because the default one is not required. So don't implement things like MyClass() {} with no special purpose - keep your code clean and save!
You can't use new with int. int is a primitive, and new is an object operator. Consider using Integer instead, or just assigning an integer literal to it.
There's nothing wrong with your if-else statement, and nothing wrong with initializing a final variable within a branching statement in a constructor. I just ran a simple constructor like yours to initialize private int right and it worked fine. Make sure that you are declaring your constructor correctly, as InitInt() { ... }.
The error you posted is because you have in your code InitInt(){}, an empty constructor that does not initialize right. You need to initialize final fields in this and all constructors.
Your constructor is absolutely Okey!!!! The problem is that you left the "right" variable uninitialized.
You have to initialize the "right" variable:
private final int right = 0;
If you only try to access the methods in the class, use this, instead of creating empty-constructor for it:
import java.io.*;
import java.util.*;
public class FileDir {
private ArrayList<Integer> lineNumbers;
FileDir(Integer nth){
lineNumbers=new ArrayList<Integer>();
lineNumbers.add(nth);
// You don't need an empty constructor
// to call class methods, use "this"
this.printHello("Davids");
}
public static void main(String[] args) {
FileDir test = new FileDir(7);
ArrayList<Integer> inteTest=test.getLineNumbers();
for (Integer i : inteTest)
System.out.println(i);
}
public void printHello(String name) { System.out.println("Hello "+ name); }
public ArrayList<Integer> getLineNumbers() { return lineNumbers; }
}