Java Static object/method issue - java

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

Related

Using an array as a parameter

I do not understand the details of using an array as a parameter:
I have created an int array and a method and I do not understand why it's possible to rename the parameter as seen below from "note" to "veraenderung".
How does Java deal with parameters? Do I need a parameter even if I call the method(note)?
public class ArrayParameter {
public static void main(String[] args) {
int[] note = {3,2,1,4,5}; //Array
int[] note2 = {3,2,1,4,5};
korrektur(note);
korrektur2(note2);
}
//Der Methode "korrektur" wird der int Array (note) übergeben!
public static void korrektur (int note[]) {
for (int i = 0; i<note.length; i++) {
//Sobald die for Schleife aufgerufen wird, werden die jeweiligen Werte um -1 reduziert
note[i]-=1;
System.out.println(note[i]);
}
}
//int "veraenderung" ist ein Parameter
public static void korrektur2 (int veraenderung[]) {
for (int i = 0; i<veraenderung.length; i++) {
//Sobald die for Schleife aufgerufen wird, werden die jeweiligen Werte um -1 reduziert
veraenderung[i]-=1;
System.out.println(veraenderung[i]);
}
}
}
i do not understand why it is possible to rename the parameter
korrektur and korrektur2 are just 2 different methods each of them having 2 independent signatures. They are not related whatsoever (even if the programmer can name them alike, just as you did);
The name of the parameters are just local names useful in the method block;
How do java deal with parameter? Do i need a parameter even if i call the method(note)?
Those methods parameters are mandatory ones. Hence you need to insert them in your method call.
I will try to break it down as small as possible for you to understand :)...
When you creating the method. example: public static void korrektur2 (int veraenderung[]) the int veraenderung[] can be named whatever you want...the main thing is that you put the "int []" somewhere within the brackets so that you tell java that "hey my method take an integer array".
The name veraenderung itself is only used locally (within that method) as a reference to tell java whatever you parse into that method will act.
For example when you call the method above and said korrektur(note); . note was declared as an array before, so when you put 'note' inside the method korrektur it is the same as replacing veraenderung with note. In other words java replaces your local variable with the one you passed into the method.
And to answer your question....for now...since you created the method which takes an integer array...YES you must always "put an integer array inside" it when calling the method. I.e. every time you call the method korrektur2 or korrekturand you do not put an integer array inside it, Java would be like "hey I was created to take an integer array and do stuff with it...why are you leaving me empty ?!?!?"
I hope this solved your questions :)
If you have seen the .class file, you'll find the parameters are the same.
you should understand the conception 'vars Scope' (may be this). Parameter 'paramArrayOfInt' have the influence korrektur(), then it be destroied. In next method ,it just new one. It's my understanding. May be wrong, welcome to discuss.
public class ArrayParameter
{
public static void main(String[] paramArrayOfString)
{
int[] arrayOfInt1 = { 3, 2, 1, 4, 5 };
int[] arrayOfInt2 = { 3, 2, 1, 4, 5 };
korrektur(arrayOfInt1);
korrektur2(arrayOfInt2);
}
public static void korrektur(int[] paramArrayOfInt)
{
for (int i = 0; i < paramArrayOfInt.length; i++)
{
paramArrayOfInt[i] -= 1;
System.out.println(paramArrayOfInt[i]);
}
}
public static void korrektur2(int[] paramArrayOfInt)
{
for (int i = 0; i < paramArrayOfInt.length; i++)
{
paramArrayOfInt[i] -= 1;
System.out.println(paramArrayOfInt[i]);
}
}
}

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.

Static public and private access in example

The question is:
Write the definition of a class Counter containing:
An instance variable named counter
of type  int .
An instance variable  named  limit of type  int  .
A static  int variable  named  nCounters which is initialized  to 0 .
A constructor  taking two int parameters  that assigns  the first one to counter and
the second one to limit . It also adds one to the static variable  nCounters .
A method  named  increment  . It does not take parameters  or return a value ; if the
instance variable  counter is less than  limit , increment  just adds one to the
instance variable  counter .
A method  named  decrement that also doesn't take parameters  or return a value ; if
counter is greater than  zero, it just subtracts one from the counter .
A method  named  getValue that returns the value  of the instance variable  counter .
A static  method  named  getNCounters that returns the value  of the static variable 
nCounters .
My Dilemma
The code works fine but I want to know the following:
Why is the first static private and the second one public?
My code:
public class Counter
{
private int counter;
private int limit;
private static int nCounters = 0;
public Counter (int x, int y)
{
counter = x;
limit = y;
nCounters++;
}
public void increment ()
{
if( counter < limit)
{
counter++;
}
}
public void decrement ()
{
if(counter > 0)
{
counter--;
}
}
public int getValue ()
{
return counter;
}
public static int getNCounters ()
{
return nCounters;
}
}
nCounters is a variable that you use to count the numbers of times the Class constructor has been called. It's static because is not a instance variable but a class variable (its value is shared by all the instances of that class).
nCounter is privated for encapsulate it. It can only be accessed outside the class by a read only method named getNCounters. Otherwise, I could access the value of nCounter and change it directly causing the value of classes created not reliable anymore.
You can read more about encapsulation and static methods and variables to understanding better your code.
The first static variable nCounters is private, because you want to control it in your class - you do not want any code outside of Counter to modify it. But you want to make it possible to read its value outside of Counter, thus the getNCounters() method is public.

"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.

Java bug or feature?

Ok, here is the code and then the discussion follows:
public class FlatArrayList {
private static ArrayList<TestWrapperObject> probModel = new ArrayList<TestWrapperObject>();
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] currentRow = new int[10];
int counter = 0;
while (true) {
for (int i = 0; i < 10; i++) {
currentRow[i] = probModel.size();
}
TestWrapperObject currentWO = new TestWrapperObject(currentRow);
probModel.add(counter, currentWO);
TestWrapperObject testWO = probModel.get(counter);
// System.out.println(testWO);
counter++;
if (probModel.size() == 10) break;
}
// Output the whole ArrayList
for (TestWrapperObject wo:probModel) {
int [] currentTestRow = wo.getCurrentRow();
}
}
}
public class TestWrapperObject {
private int [] currentRow;
public void setCurrentRow(int [] currentRow) {
this.currentRow = currentRow;
}
public int [] getCurrentRow() {
return this.currentRow;
}
public TestWrapperObject(int [] currentRow) {
this.currentRow = currentRow;
}
}
What is the above code supposed to do? What I am trying to do is load an array as a member of some wrapper object (TestWrapperObject in our case). When I get out of the loop,
the probModel ArrayList has the number of elements it is supposed to have but all have the same value of the last element (an array of size 10 with each item equal to 9). This is not the case inside the loop. If you perform the same "experiment" with a primitive int value everything works fine. Am I missing something myself regarding arrays as object members? Or did I just encounter a Java bug? I am using Java 6.
You are only creating one instance of the currentRow array. Move that inside the row loop and it should behave more like you expect.
Specifically, the assignment in setCurrentRow does not create a copy of the object, but only assigns the reference. So each copy of your wrapper object will hold a reference to the same int[] array. Changing the values in that array will make the values appear to change for all other wrapper objects that hold a reference to the same instance of the array.
i don' t want to sound condescending, but always try to remember tip #26 from the excellent pragmatic programmer book
select isn't broken
it is very rare to find a java bug. keeping this in mind often helps me to look over my code again, turn it around, and shake out the loose bits until i finally discover where i was wrong. of course asking for help early enough is very encouraged, too :)

Categories

Resources