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.
Related
Why is my method not returning anything?
class Test{
static int count = 0;
public static void main(String args[]){
String s = "------+ # ----+------";
countDoors(s);
}
public static int countDoors(String s){
char sigN= '+';
for(int i=0;i<s.length();i++)
if(s.charAt(i)==sigN)
count++;
return count;
}
}
I'm sure kinda a noobish question, but I really wanna understand why it isn't working
In main() method, you call countDoors(s);, it returns count value, but you do nothing with it.
If you want to just print this value to console, then change countDoors(s); to System.out.println(countDoors(s));
If you want to save the result of calling countDoors(s) to the variable to make a use of it later, there is an example how you can achieve it:
int savedValue = countDoors(s);
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.
Let me explain further. I have a String function (called stringReversal) that returns a reversed string, it has no errors in the function. But, when I try to print using System.out.println() from the main function, it gives me the error "Can not make a static reference to the non static method stringReversal (string s) from the type StringReverse".
I tried giving my stringReversal a static modifier, but after doing so, it gave me run time errors.
Here's what my code looks like:
public class StringReverse {
public String stringReversal(String s){
if(s == null){
return null;
}
else if(s.length()% 2 == 0){
int size = s.length();
for(int i =0; i<s.length(); i++){
s.replace(s.charAt(i), s.charAt(size));
size--;
if(i == (s.length()/2) || size==0)
break;
}
}
else{
for(int i =0; i<s.length(); i++){
int size = s.length();
s.replace(s.charAt(i), s.charAt(size));
size--;
if(i == ((s.length()/2) +1) || size==0 )
break;
}
}
return s;
}
public static void main(String[] args) {
String str = "Hello";
String rev = stringReversal(str);
System.out.println();
}
}
You have to instantiate your class to call object members, or you need to make your function static, indicating it's not part of object oriented paradigm
In your case you can do
StringReverse sr = new StringReverse();
String rev = sr.stringReversal("hello");
or declare your method differently
public static String stringReversal(String s)
In fact the class name StringReverse itself does not sound like some kind of object, so the second way is preferred impo
The deeper problem you have is the confusion on how Java handle OO and entrance function in general. Java is primarily an OO language so most of the time everything shall be an object or a member of a object. But when you telling the VM to run some java code, there got to be a place to start, which is the main method. There has to be one main method and it must be under some class, but it really has nothing to do with the class that contains it. Within the main method, you either start your OO life by instantiating objects and invoking their members (method 1) or stay in the spaghetti world for a bit longer, by calling other static members as procedures (method 2).
You have two options:
Keep the method non static and then create an instance of your class to call the method:
public static void main(String[] args) {
String str = "Hello";
StringReverse sr = new StringReverse(); // instance of class
String rev = sr.stringReversal(str);
System.out.println(); // just prints a blank line lol...
}
Make the method static (you should do this):
public static String stringReversal(String s) {
// ...
}
public static void main(String[] args) {
String str = "Hello";
String rev = stringReversal(str);
System.out.println(); // just prints a blank line lol...
}
Either way, you have to fix your "run time errors". You can't get around that. If your method doesn't work, keeping it not static won't make it work either.
By the way, I think you meant to do System.out.println(rev); instead of System.out.println();
For the record, here is how to easily reverse a string (both methods work):
public static String stringReversal(String s) {
StringBuffer reverseString = new StringBuffer();
// reverse the string
for (int i = s.length() - 1; i > -1; i--) {
reverseString.append(s.charAt(i));
}
return reverseString.toString();
}
/* using the reverse() method in the StringBuffer class
instead of reversing the string through iterations */
public static String stringReversal2(String s) {
return new StringBuffer(s).reverse().toString();
}
This is happening because your Main method is static, but the class that it's in is not. In order to call a non-static method, you need to create an instance of the class. Alternatively, the method can be made static, but in order to refer to it you need to include the class name in your call (as if to use the class itself like an object containing the method - see below).
There are three solutions to this problem:
Make an instance of the class and call the method from your object (recommended).
make the method static and use StringReverse.stringReversal().
Make the class AND the method static.
I got a question about how to use static, I saw a sample:
public class Exe {
static int i = 47;
public void call() {
for (i = 0; i < 3; i++) {
if (i == 2) {
System.out.println("\n");
}
}
}
public Exe() {
}
public static void main(String[] args) {
Exe t1 = new Exe();
Exe t2 = new Exe();
t2.i = 60;
System.out.println(t1.i);
t1.call();
System.out.println(t2.i);
t2.call();
}
}
When I tried to run it, it printed 60 3, I am wondering why t2.i here is 3, I do not know where the 3 comes from, also, the both results of t1.call() and t2.call() were not printed, please advise, thank you!
for(i=0; i<3;i++){
if(i==2){
System.out.println("\n");
}
}
Your static variable Assigned/incremented here.
Not the i (which you are assuming, it's different) in for loop.
To clear the clouds, Just take another variable called j and do the looping.
for (int j = 0; j < 3; j++) {
if (j == 2) {
System.out.println("\n");
}
}
static means that every instance of the class has access to the same, single instance of the variable.
When you create t1, t1.i is initialized to 47. Then you create t2. t2.i and t1.i are the same variable, so whether you do t1.i = 60 or t2.i = 60, they're BOTH equal to 60.
So before you do t1.call(); or t2.call(), the first thing you do is print out t1.i, which is 60, as per the line t1.i = 60;.
Then you run t1.call() which runs through the for loop. The for loop exits when i can't pass the test i < 3, and since i is an integer, this happens as soon as i is incremented to 3.
After you've run t1.call(), i is now equal to 3. This means both t1.i and t2.i since static means there's only one copy of i across all instances of the Exe class here. So you print out t2.i and it is equal to 3, as it should be.
Hope this helps.
The 3 comes from your for loop, which is reusing the same static int i that you're manually setting to 60 before you call call(). The results of the println probably are being printed, but they're just blank lines.
for (i = 0; i < 3; i++)
In this statement instead of treating i as a local variable it is taken to be class variable which you defined. As for class variables only one copy is maintained for all the instance after the for loop finished(i=3) value of you class variable i remains to be 3.
Your static variable is the same across all objects, this is an effect of static. This means that when you call t2.i = 60; both t1.i and t2.i are set equal to 60. Then when you call t1.call(); you again change both objects. As others have explained your for loop is setting the variable i = 3.
It's because it's a static variable that the assignment affects both objects
Static members doesn't reflect the object state!
All objects of a class will have the same copy(mean to say same value) of the static variables. If one object changes the value of a static variable, since the static variable holds the same value across all the objects, the static variable value will be updated across all the objects of that class. This rule reflects your result.
See the below example:
public class StaticTest {
static int staticA = 10;
int intA;
public StaticTest(int intA){
this.intA = intA;
}
public static void main(String[] args) {
StaticTest test1 = new StaticTest(10);
System.out.println(test1.intA);
System.out.println(test1.staticA);
StaticTest test2 = new StaticTest(20);
System.out.println(test2.intA);
System.out.println(test2.staticA);
}
}
Below is the outpput:
10
10
20
10
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);
}
}