Can instance variable be declared as static variable in java - java

I wrote the following code:
public class Count
{
private static int[] array;
public Count( int[] array )
{
this.array = array;
}
public int count()
{
int count = 0;
for (int i = 0; i < array.length; i++) {
int x = array[i];
if (x < 0) {
if (x == -1 && i > 0 && array[i - 1] == -1) {
break;
}
} else {
count++;
}
}
return count;
}
}
and then in another class I wrote:
Count c = new Count(new int[]{1,-1,-1});
and checked the result of c.count().
I didn't get a compiler error,and I got 1 as I wanted.
I wonder why because how can I assign a static variable to an instance variable?
And also, what happens if I create another instance of class Count?
Will they both have the same variable?or just their own copy of it? and what should happen if I try to access the variable by writing Count.array?
Thanks.

array is shared between all the instances of Count - they can all read from it and write to it. And as you stated, if you instance modifies it, all the other instances will see the newly modified value.

Classes can access their own static members.
All classes will see the same static members (ignoring thread contention complications).
If you create another instance of Count they will both be modifying the same variable.
That's what static means...

I'd recommend that you write the example you're asking about and see. There's no better authority than the JVM, and it'll tell you faster than SO will.
I think you should understand the meaning of class and instance variables and pick the one that matches your intent.
So it's either class:
public class Count
{
// Shared by all
private static int[] array;
}
or instance:
public class Count
{
// Owned by instance
private int[] array;
public Count(int [] v) {
if (v == null) throw new IllegalArgumentException("array cannot be null");
this.array = new int(v.length);
System.arraycopy(v, this.array, 0, v.length);
}
}
You should not just assign the array reference to the private data member. You need to allocate memory and copy the values into it. Otherwise the supplier of the input array will modify the private values if it updates using their reference.
Too many people don't realize that assigning mutable references to private members breaks encapsulation. Maybe you won't be one of them now.

Related

Java : Static methods

I am at beginner stage in learning java, I made a program for bubble sort. Code is as follows
package bubblesort;
public class Bubblesort {
public static void main(String[] args) {
int[] arr = new int[] {10,20,40,30,50};
arr = BubbleSort(arr);
for(int i:arr) {
System.out.println(i+" ");
}
}
public static int[] BubbleSort(int[] arr) {
int temp;
for(int i = 0;i<arr.length;i++) {
for(int j =i+1;j<arr.length;j++) {
if(arr[i] > arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
}
My question is as following :
"Since a static method can only take static data variables as parameters, then why 'BubbleSort' function in my program is not reporting any error because of arr not being a static variable ?"
Since a static method can only take static data variables as parameters
Incorrect.
A static method can only directly reference other static members, not instance members. This refers to class-level fields, methods, etc.
But any method can accept as a parameter/argument any value you pass to it. And can internally declare and use any local variable it wants.
A static method can only access static members of its containing type. So in your case the BubbleSort method cannot access any instance fields or methods of the BubbleSort class. Arguments and local variables are of course always allowed.
Static methods neither know nor care where the parameters came from in the first place. It doesn't matter that it's a local variable because it has a reference to the array.
What you actually can't do is "directly" refer to instance methods or fields from a static method because, by definition, it needs a specific instance to call those methods on.

writing a static method to set counter java?

I am pretty new to coding, I want to write a static method to set a count value to 1000.
I tried doing things like
public static int setCounter(){
return 1000;
}
When try to use this method in another to increment the count
such as someVariable = symbolic constant + setCounter()++;
return someVariable, it gives me an unexpected type error, required variable, found value. What am i doing wrong?
edit*
edit*
private String getTicketNumber(){
ticketNumber = TICKET_PREFIX + resetCounter()++;
return ticketNumber;
public static int resetCounter(int counter){
counter = 1000;
}
i want to call this counter to increment it in another method
An static property is associated with the definition of the class, and there is only ever one definition of the class. An instance is created whenever you use the new keyword on the class. All instances are keep their own private data from the static class. When using a class instance you can access the static variables but not the other way around.
You use the term constant, but I think you might have a bit of a misunderstanding of what that implies. Constants are often declared as static final values that are immutable (they can never be changed). You should not be able to modify a constant. A static value can be mutable if you so desire, and this is what we would sometimes refer to as a stateful singleton.
Consider these two examples... one modifies an instance variable, the other a static variable.
class InstanceFoo {
int i = 1000;
int resetCounter() {
i = 1000;
return i;
}
int getAndIncrement() {
return i++;
}
}
class StaticFoo {
static int i = 1000;
static int resetCounter() {
i = 1000;
return i;
}
static int getAndIncrement() {
return i++;
}
}
In the first example you need to use an instance to access the variables.. i.e. you need to instantiate it with new:
InstanceFoo foo = new InstanceFoo();
System.out.println(foo.resetCounter()); // 1000
System.out.println(foo.getAndIncrement()); // 1000
System.out.println(foo.getAndIncrement()); // 1001
System.out.println(foo.getAndIncrement()); // 1002
System.out.println(foo.resetCounter()); // 1000
In the second you access the static value. Statics can be referred to by to the class definition:
System.out.println(StaticFoo.resetCounter()); // 1000
System.out.println(StaticFoo.getAndIncrement()); // 1000
System.out.println(StaticFoo.getAndIncrement()); // 1001
System.out.println(StaticFoo.getAndIncrement()); // 1002
System.out.println(StaticFoo.resetCounter()); // 1000
In your example you are trying to increment the counter by doing resetCounter()++. This will not work for a separate reason entirely from being static or instance. Primitive values in Java (like ints, doubles, floats, etc) are pass by value, not pass by reference.
In a very simplistic sense, this means that once you return a primitive from a method like resetCounter, you are actually passing a copy of the value. You then incremented the copy, but the value associated with the class remains the same (because you incremented only the copy of the variable). You need to call the postfix operator ++ on the variable itself, not the value returned by the method. i.e. If I have
class StaticFoo {
static int i = 1000;
static int get() {
return i;
}
}
System.out.println(StaticFoo.get()++); // prints 1000 and adds 1. the copy is then destroyed
System.out.println(StaticFoo.get()++); // prints 1000 and adds 1, the copy is then destroyed
System.out.println(StaticFoo.i); // prints 1000
System.out.println(StaticFoo.i++); // prints 1000 and now a postfix is applied to the static variable
System.out.println(StaticFoo.i++); // prints 1001 and another postfix is applied to the static variable
System.out.println(StaticFoo.get()); // prints 1002 because two postifx operators were applied to StaticFoo.i.
Hope this helps you get started.
I think that you are assigning value to a non compatible data type varaiable.
See my code for reference:
public class Main
{
public static void main(String[] args) {
System.out.println("Hello World");
int a = 10 + setCounter();
System.out.println(a);
}
public static int setCounter(){
return 1000;
}
}
edit*
private String getTicketNumber(){
ticketNumber = TICKET_PREFIX + resetCounter()++;
return ticketNumber;
public static void resetCounter(int counter){
counter = 1000;
}
i want to call this counter to increment it in another method

How to make static variable of object A immutable to state changes on object B

If I have some simple class such as. The problem is instance B of this class can impact instace A's j.
public class Tester {
private static int j;
public Tester() {
}
public void setJ(int i){
this.j = i;
}
public int getJ() {
return j;
}
}
In my real world application, j needs to be static (so private static classes can use it). However I encounter a problem when I make it static which is in the above example. If we create two separate instances of this class I can show the problem:
Tester testOne = new Tester();
Tester testTwo = new Tester();
testOne.setJ(1);
testTwo.setJ(2);
System.out.println(testOne.getJ()); //returns 2
then by setting the static variable in testTwo, it overwrites what I previously set as for the static variable in testOne. If I was to remove static then j would be immutable with respect to testTwo.setJ(2), but I can't have this.
How do I fix this problem?
this is not a bug, it's correct behavior. If you really need smtg like you've just explained, you may try such way:
public class Tester {
private static int j;
private boolean jWasSet;
public Tester() {
}
public void setJ(int i){
if (!jWasSet) {
this.j = i;
jWasSet = true;
}
public int getJ() {
return j;
}
}
if a variable is made static then if you change once then it will be reflected everywhere
When you are doing testOne.setJ(1); the variable is set to 1 but again you are calling testTwo.setJ(2); so again the variable is set to 2,so finally you are getting 2
In my real world application, j needs to be static (so private static classes can use it).
you can create an object then call the instance variable without making it static
Static fields will be common to all instances of the Class. In your case, since j is static, its common to any number of instances you create for the class. That's change made by 1 instance will be reflected in the other.
See it like this.
There is a static `j` - since its static, it'll be initialized to 0 by default.
j = 0 // initially
testOne.setJ(1) // This makes j = 1
j = 1 // Now
testTwo.setJ(2) // This makes j = 2, since j is shared by all instances of your class(property of static fields)
j = 2 // Finally

how avoid set a global variable in recursive class

I have a global variable in a recursive class, each time I call it, the variables are created. The variable at begin is: int count = 0, then in the method I increase: count ++, the problem is when call again the class, the variable is reset to zero. I need the variable "count" remains in 1, to again increase in each call to 2,3,4.... etc
I try with this: private static int count = 0; but not work..
Search the code for all references to your count variable. Most likely, you are re-setting to 0 somehow. For example:
private class MyClass {
private static int count = 0;
public MyClass() {
count = 0; //Bad line
}
public void incrementCount() {
count++;
}
}
If you have something like that, then every time you create a new MyClass object, you would be resetting count to 0 for all MyClass objects.
But you really need to add your class code to your question. Otherwise we can't help.

java Integer reference

I've got a question.
public class Jaba {
public static void main(String args[]) {
Integer i = new Integer(0);
new A(i);
System.out.println(i);
new B(i);
System.out.println(i);
int ii = 0;
new A(ii);
System.out.println(ii);
new B(ii);
System.out.println(ii);
}
}
class A {
public A(Integer i) { ++i; }
}
class B {
public B(int i) { ++i; }
}
To my mind passing an int\Integer as Integer to a function and making ++ on that reference should change the underlying object, but the output is 0 in all the cases. Why is that?
Most of the classes such as Integer that derive from Java's abstract Number class are immutable., i.e. once constructed, they can only ever contain that particular number.
A useful benefit of this is that it permits caching. If you call:
Integer i = Integer.valueOf(n);
for -128 <= n < 127 instead of:
Integer i = Integer.new(n)
you get back a cached object, rather than a new object. This saves memory and increases performance.
In the latter test case with a bare int argument, all you're seeing is how Java's variables are passed by value rather than by reference.
#Alnitak -> correct. And to add what really happens here. The ++i due to autoboxing works like that:
int val = Integer.intValue(); ++val;
and val is not stored anywhere, thus increment is lost.
As said in the other answers, Java does only call-by-value, and the ++ operator only effects a variable, not an object. If you want to simulate call-by-reference, you would need to pass a mutable object, like an array, and modify its elements.
The Java API has some specialized objects for this, like java.util.concurrent.atomic.AtomicInteger (which additionally also works over multiple threads), and org.omg.CORBA.IntHolder (used for call-by-reference for remote calls by the CORBA mechanism).
But you can also simply define your own mutable integer:
class MutableInteger {
public int value;
}
class C {
public C(int[] i) {
++i[0];
}
}
class D {
public D(MutableInteger i) {
++i.value;
}
}
class E {
public E(AtomicInteger i) {
i.incrementAndGet();
}
}
public class Jaba {
public static void main(String args[]) {
int[] iii = new int[]{ 0 };
System.out.println(iii[0]);
new C(iii);
System.out.println(iii[0]);
MutableInteger mi = new MutableInteger();
System.out.println(mi.value);
new D(mi);
System.out.println(mi.value);
MutableInteger ai = new AtomicInteger(0);
System.out.println(ai);
new E(ai);
System.out.println(ai);
}
}
If you want to use reference parameter then try this.
IntHolder
http://docs.oracle.com/javase/7/docs/api/org/omg/CORBA/IntHolder.html

Categories