Illegal forward Reference java issue - java

Could anyone explain what is wrong with this code:
public class Base {
static {
i = 1;
System.out.println("[Base]after static init block i=" + i);// LINE 1
System.out.println("*************************************");
System.out.println();
}
static int i;
public static void main(String[] args) {
System.out.println(Base.i);
}
}
If I comment LINE 1 - everything is OK and Base.main method prints "1".
If LINE 1 - is not commented, got compile time error: "illegal forward reference".
So, as i understand in static init block I can set value for i, but not read. Could anyone explain why?

This is because of the restrictions on the use of Fields during Initialization. In particular, the use of static fields inside a static initialization block before the line on which they are declared can only be on the left hand side of an expression (i.e. an assignment), unless they are fully qualified (in your case Base.i).
So for example: if you insert int j = i; right after i = 1; you would get the same error.
The obvious way to solve the issue is to declare static int i; before the static initialization block.

"Illegal forward reference" means that you are trying to use a variable before it is defined.
The behavior you observe is a symptom of a javac bug(see this bug report). The problem appears to be fixed in newer versions of the compiler, e.g. OpenJDK 7.
have a look at
Illegal forward reference error for static final fields

You can add Base to your i variable in static block or you have to declare static int i before the block. Other solution is to create static method instead of static block.
static {
Base.i = 1;
System.out.println("[Base]after static init block i=" + Base.i);// LINE 1
System.out.println("*************************************");
System.out.println();
}

Change your code to:
int i;
static {
i = 1;
System.out.println("[Base]after static init block i=" + i);// LINE 1
System.out.println("*************************************");
System.out.println();
}

A variable should always be textually declared before used else Illegal forward Reference comes into picture. Only Exception to this Statement is : If prior to declaration it is used on LHS of expression. Ex :
Snippet 1:
static{
x = 10;
}
static int x;
Above snippet will work.
Snippet 2:
static{
System.out.println("Value of x: " + x)
}
static int x;
This will give CTE, because x isnt LHS of expression.
Keeping those conditions in mind we can avoid Illegal Forward ref issue in our code.
Thanks

public class Base {
static {
i = 1;
System.out.println("[Base]after static init block i=" +Base.i);// illegal start of expression
System.out.println("*************************************");
System.out.println();
}
static int i;
public static void main(String[] args) {
System.out.println(Base.i);
}
}

Related

Trying to print a method using another method

Not sure where I'm going wrong with this. I've asked someone in my class and they said there should be an argument with "toonRijSterren". when I do this I just get more errors, could someone have a look and tell me where I'm going wrong?
public static void main(String[] args) {
int aantal = 0;
toonRijSterren(aantal);
toonSterrenVierkant(aantal);
}
public static void toonRijSterren(int mpAantal) {
while (mpAantal < 6) {
System.out.print(" * ");
mpAantal++;
}
}
public static void toonSterrenVierkant(int mpAantal) {
for (int mpAatal = 0; mpAantal < 6; mpAantal++) {
System.out.println(toonRijSterren());
}
}
ther error line is in the brackets of the last toonRijSterren());
toonRijSterren is void method which means it does not return any value and therefore you can not put it inside System.out.println() or you can not assign it to some variable.
toonRijSterren expects an int argument which you have missed while calling it.
Given below is an example of how you should call toonRijSterren:
public static void toonSterrenVierkant(int mpAantal) {
for (int mpAatal = 0; mpAatal < 6; mpAatal++) {
toonRijSterren(mpAantal);
}
}
You are not passing the argument when you call your method.
Try this:
System.out.println(toonRijSterren(mpAatal));
First of all, your function toonRijSterren takes an int type parameter (according to its declaration), so you need to pass to it another argument. For example:
toonRijSterren(mpAantal)
Second, the function toonRijSterren returns void. That means, it just does an operation (in this case, printing) without returning anything. What you're trying to do is to use its return value (which doesn't exist) as an argument to System.out.println, which causes an error (because println expects an argument of some type).
You could achieve what I think you're trying to do with the line:
toonRijSterren(mpAantal);.
The function itself prints the values, so the println here is unnecessary and causes an error.
You are missing the parameter in your toonSterrenVierkant() function where you calling toonRijSterren.
Here is the corrected version of your code:
public static void toonSterrenVierkant(int mpAantal) {
for (; mpAantal < 6; mpAantal++) {
toonRijSterren(mpAatal);
}
}
As your methed toonSterrenVierkant(int mpAantal) has a int parameter, you must pass an int value as an argument in the last toonRijSterren(). For example, replace the line System.out.println(toonRijSterren()); with System.out.println(toonRijSterren(1));

error: multiply(long) is not public in BigInteger; cannot be accessed from outside package

I'm trying to write a Java method that uses counts the number of ways to sequentially order n distinct objects - a permutation. Every time I try to complile my code, I get an error saying:
multiply(long) is not public in BigInteger; cannot be accessed from outside package.
I tried replacing the line fact = fact.multiply(i); with fact = fact.multiply((long) i); which didn't work either. Does anyone have any ideas?
import java.math.BigInteger;
public class Combinatorics {
public static void main(String[] args) {
// 2.1
System.out.println(CountPerm(9));
}
public static BigInteger CountPerm(int n) {
BigInteger fact = BigInteger.valueOf((long) 1);
for(int i = 1; i <= n; i++){
fact = fact.multiply(i);
}
return fact;
}
}
To multiply BigIntegers, you need give a BigInteger parameter, not a long parameter. The method is BigInteger.multiply(BigInteger).
Change your code to:
fact = fact.multiply(BigInteger.valueOf(i));
As a side note:
BigInteger.valueOf((long) 1); should be replaced by BigInteger.ONE. There is already a predefined constant for one.
Be sure to respect Java naming conventions: CountPerm method should be called countPerm.

why can we use the new operator before the class is loaded

Considering the code below, it runs without throw any exception.
public class Test1 {
public static int k = 0;
public static Test1 t1 = new Test1("t1");
public static Test1 t2 = new Test1("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
{
print("constructor block");
}
static {
print("static block");
}
public Test1(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++i;
++n;
}
public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
return ++i;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Test1 t = new Test1("init");
}
}
output :
1:j i=0 n=0
2:constructor block i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:constructor block i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:static block i=7 n=99
9:j i=8 n=100
10:constructor block i=9 n=101
11:init i=10 n=102
I step through it with a debugger.
can see the clinit method calls init method. Since the clinit method is still a part of class loading, does this mean we can instantiate Test1 object before the Test1 class is well prepared?
I'd have to look up the exact definition in the spec (you can do that as well) but let's put it that way:
Suppose you have the following:
class A {
static B b = new B();
}
class B {
static A a = new A();
}
If the classes would have to be fully initialized before creating new instances, i.e. all static initializers would have to run, you'd have a deadlock. Not allowing to create new instances in a static block would severely limit the language and thus there must be some way to resolve this.
As I said, I'd have to look this up but AFAIK the default order is like this:
classes are loaded and static variables are initialized to their defaults
as constructors are called top-down (i.e. from super class to sub class)
first the static initializer blocks (i.e. initializing static variables as well as static blocks) are called in order of definition
then the instance initializer block for the current class is executed and
last the constructor is executed
Of course there are ways to mess with that order as you already found out but that's generally not recommended since you could end up with undefined/messy behavior. One such case would be calling a method in the super class constructor which is being overridden in the subclass and which accesses (not yet initialized) fields of the subclass.

error on calling static method from void java

Need help on calling a method from main class.
I need to call a method, thus I made an object to handle it.
below I quote my main method
public static void main(String[] args) {
// TODO code application logic here
SLRatio sl= new SLRatio();
sl.clustering(apa);
}
and here's the method I need to call
public class SLRatio {
public static String [][]clustering(String[][]apa) {
System.out.println("Cluster 1");
int a = apa.length/3;
String [][] cluster1=new String [a][apa[0].length];
for (int i =0; i<a; i++) {
for (int j=0;j<apa[0].length;j++) {
cluster1 [i][j] = apa[i][j];
}
}
for (int b = 0; b < cluster1.length; b++) {
for (int c = 0; c < cluster1[0].length; c++) {
System.out.print(cluster1[b][c] + "\t");
}
System.out.println("");
}
System.out.println("\n");
return cluster1;
}
}
and I got error message:
"Cannot find symbol,Accessing static method clustering"
What can I do to solve it? I have tried to change the syntax but it didn't work.
Thank you so much.
you didn't define method Allocation() in SLRatio
Note: static method should be called with classname (to avoid confision between instance method and static)
If it is static method, you don't need to call it through instance.
SLRatio .clustering(...);
should be enough.
And it seems you forgot to implement Allocation method.
Another suggestion, java naming convention, method name starts with small case letters.
Do not use static unless you are sure it is appropriate.
This is a popular programming error, partially because eclipse keeps on suggesting to make variables and methods static when they cannot be accessed. But usually, this is not the correct solution. While it fixes the compilation problem, it often breaks the application logic.
Right now, your problem probably is that apa has type String[][], but you are passing a String[] parameter to it. So it cannot be compiled, because there is no method clustering(String[] args).
Seriously, you need to learn more Java basics. Maybe from a book.

"non-static variable this cannot be referenced from a static context"?

I'm a Java newbie and I'm trying to deploy a fibonacci trail through recursive function and then calculate the run time.
here is the code I have managed to write:
class nanoTime{
int fib(int n){
if(n==0) return 0;
if(n==1) return 1;
return this.fib(n-1)+this.fib(n-2);
}
public static void main(String[] args){
double beginTime,endTime,runTime;
int n=10;
beginTime = System.nanoTime();
n = this.fib(n);
endTime = System.nanoTime();
runTime = endTime-beginTime;
System.out.println("Run Time:" + runTime);
}
}
The problem is when I'm trying to turn it into Byte-code I get the following error:
nanoTime.java:11: non-static variable this cannot be referenced from a static context
I'm wondering what is the problem?!
Change
n = this.fib(n);
to
n = fib(n);
and make the method fib static.
Alternatively, change
n = this.fib(n);
to
n = new nanoTime().fib(n);
You need to instantiate a nanoTime to call an instance method, or make the fib method static as well.
The problem is just what the message says. Your main method is static, which means it is not linked to an instance of the nanoTime class, so this doesn't mean anything. You need to make your fib method static as well, and then use nanoTime.fib(n).
There is no reason to use this in your code.
Steps to take:
Rename your class to anything that starts with an upper case letter
Remove all this from your code
Add the static keyword before int fib(int n){
Finally get a good Java book! ;)
# Name the class something else to avoid confusion between System.nanoTime and the name of your class.
class nanoTime1{
int fib(int n){
if(n==0) return 0;
if(n==1) return 1;
return this.fib(n-1)+this.fib(n-2);
}
public static void main(String[] args){
double beginTime,endTime,runTime;
int n=10;
beginTime = System.nanoTime();
# Instantiate an object of your class before calling any non-static member function
nanoTime1 s = new nanoTime1();
n = s.fib(n);
endTime = System.nanoTime();
runTime = endTime-beginTime;
System.out.println("Run Time:" + runTime);
}
}
Be careful ! In Java the main has to be in a class definition, but it's only the entry point of the program and absolutely not a method of the object/class.
Change this.fib(n) to :
nano obj = new nano();
n = obj.fib(n);
this is associated with the instance of the class. A static method does not run with a class instance but with the class itself. So either change the fib method to static or replace the line where you call fib to the above two lines.

Categories

Resources