java Integer reference - java

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

Related

A reference to primitive type in Java (How to force a primitive data to remain boxed)

I would like to pass a reference to a primitive type to a method, which may change it.
Consider the following sample:
public class Main {
Integer x = new Integer(42);
Integer y = new Integer(42);
public static void main(String[] args) {
Main main = new Main();
System.out.println("x Before increment: " + main.x);
// based on some logic, call increment either on x or y
increment(main.x);
System.out.println("x after increment: " + main.x);
}
private static void increment(Integer int_ref) {
++int_ref;
}
}
The output running the sample is:
x Before increment: 42
x after increment: 42
Which means int_ref was past to the function by value, and not by reference, despite my optimistic name.
Obviously there are ways to work around this particular example, but my real application is way more complex, and in general one would imagine that a "pointer" or reference to integer would be useful in many scenarios.
I've tried to pass Object to the function (then casting to int), and various other methods, with no luck. One workaround that seems to be working would be to define my own version of Integer class:
private static class IntegerWrapper {
private int value;
IntegerWrapper(int value) { this.value = value; }
void plusplus() { ++value; }
int getValue() { return value; }
}
Doing this, and passing a reference to IntegerWrapper does work as expected, but to my taste it seems very lame. Coming from C#, where boxed variable just remain boxed, I hope I just miss something.
EDIT:
I would argue my question isn't a duplicate of Is Java "pass-by-reference" or "pass-by-value"?, as my question isn't theoretical, as I simply seek a solution. Philosophically, all method calls in all languages are pass-by-value: They either pass the actual value, or a reference to the value - by value.
So, I would rephrase my question: What is the common paradigm to workaround the issue that in java I'm unable to pass a reference to an Integer. Is the IntegerWrapper suggested above a known paradigm? Does a similar class (maybe MutableInt) already exist in the library? Maybe an array of length 1 a common practice and has some performance advantage? Am I the only person annoyed by the fact he can store a reference to any kind of object, but the basic types?
Integer is immutable, as you may notice.
Your approach with private static class IntegerWrapper is correct one. Using array with size 1 is also correct, but in practice I have never seen using array for this case. So do use IntegerWrapper.
Exactly the same implementation you can find in Apache org.apache.commons.lang3.mutable.MutableInt.
In your example you also can provide Main instance to the static method:
public class Main {
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
incrementX(main);
}
private static void incrementX(Main main) {
main.x++;
}
}
And finally, from Java8 you could define an inc function and use it to increment value:
public class Main {
private static final IntFunction<Integer> INC = val -> val + 1;
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
main.x = INC.apply(main.x);
}
}

Error in Creating Java array with Multiple Data Types

Can someone please explain why it doesn't work? The error is at obj[0][0]=1;. It says that GPA can't be converted to int, same thing for String variable assignment s.
public class GPA {
public String s;
public int n;
public GPA[][] a;
//constructor
public GPA(GPA[][] a){}
public static void main(String[] args) {
GPA[][] obj=new GPA[2][2];
obj[0][0]=1; //error here
}
}
obj is an Array of GPA objects.
obj[0] = 1 means you are assigning the first element of that array to an intvalue. It should be an object of type GPA.
You can do it like
obj[0] = new GPA("John Doe", 6);
I would also recommend using Java convention, by making variables private and set() them by public methods like setter()s.
The question is changed which makes the answer irrelevant.
It won't work and gives you compile time error because GPA is class type and you are trying to assigning int value to it.
You have two options.
Option 1:
GPA[] obj = new GPA[4];
obj[0] = new GPA();
obj[0].n = 1;
Option 2:
You can make members of GPA private and use setters to set the value. Below is example.
public class GPA {
private String s;
private int n;
private GPA[] a;
public GPA() {}
public GPA(GPA[] a) {}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public GPA[] getA() {
return a;
}
public void setA(GPA[] a) {
this.a = a;
}
}
and then set using setter.
obj[0].setN(1);
It's not good programming practice to make your members public. It is always advised to use setters.
What you're actualy doing is trying to assign int and/or string to variable that is expecting object of GPA class.
Didn't you want to do
obj[0].n=1;
obj[0].s="text;"
For array of object you always have to create on object at that position first. otherwise you alway get a NullPointerException.
So what you need goes something like this
GPA[][] obj = new GPA[2][2];
obj[0][0] = new GPA();
obj[0][0].s="text";
obj[0][0].n=1;
...
and so on for every position there is.
Java Arrays are homogeneous(Javascript arrays are heterogeneous). That means you can only store the type of elements which you used while creating an Array.
ex: `int intArray[];` //We can store only int type elements(it also accepts Integer etc.. types but java converts to int then store it)
Now, apply the same rule to public GPA[] a; here a is an array of type GPA. So it accept only GPA type object.
That mean, you can store values like as below
a[0] = new GPA("nameHere", 6);
If I want to store either a string or an int, one at a time( I have
to make table of Student Name vs GPA) ,how do I do it?
One solution to this requirement is, assign a variable using constructor or setter method.
GPA[] obj = new GPA[2];
obj[0] = new GPA("first", 6); // here you need to create a new constructor
or
obj[1] = new GPA(); // Here default constructor will work and you need to have setter methods
obj[1].setName("second");
Hope this help...

Is there a Integer class in c#?

We have Integer class in JAVA, but I couldn't find any equivalent class in C#? Does c# have any equivalent? If not, how do I get JAVA Integer class behavior in c#?
Why do I need this?
It is because I'm trying to migrate JAVA code to c# code. If there is an equivalent way, then code migration would be easier. To addon, I need to store references of the Integer and I don't think I can create reference of int or Int32.
C# has a unified type system, so int can be implicitly boxed into an object reference. The only reason Integer exists in Java is so that it can be converted to an object reference and stored in references to be used in other container classes.
Since C# can do that without another type, there's no corresponding class to Integer.
Code migration won´t work out of the box for any type of language without any manual changes. There are things such as a class Integer that simply does not exist within (C# why should it anyway, see recursives answer), so you´d have to do some work on your own. The nearest equivalent to what you´re after is Int32 or its alias int. However you may of course write your own wrapper-class:
public class Integer
{
public int Value { get; set; }
public Integer() { }
public Integer( int value ) { Value = value; }
// Custom cast from "int":
public static implicit operator Integer( Int32 x ) { return new Integer( x ); }
// Custom cast to "int":
public static implicit operator Int32( Integer x ) { return x.Value; }
public override string ToString()
{
return string.Format( "Integer({0})", Value );
}
}
The beauty of C# is that it has a unified type system. Everything derives from object, even primitive types. Because of this, all keywords are simply aliases for a corresponding class or struct. Java does not use a unified type system, so a separate Integer class is required to wrap the int primitive. In C# int is synonym for the Int32 struct.
What you're looking for has been right in front of you the whole time. Start using the dot notation directly on the int keyword (i.e. int.whatever()) to access the all goodness of the .NET version of the Javian Integer class.
I did some testing with Nullable types in a console application and it appears that they do not behave as you wish. For example:
static void Main(string[] args)
{
int? x = 1;
Foo(ref x);
Console.WriteLine(x);//Writes 2
}
private static void Foo(ref int? y)
{
y += 1;
var l = new List<int?>();
l.Add(y);
l[0] += 1;//This does not affect the value of x devlared in Main
Console.WriteLine(l[0]);//Writes 3
Console.WriteLine(y);//writes 2
Foo2(l);
}
private static void Foo2(List<int?> l)
{
l[0] += 1;
Console.WriteLine(l[0]);//writes 4
}
But if you roll your own generic class to wrap primitive/value types for use within your application you can get the behavior you are expecting:
public class MyType<T>
{
public T Value { get; set; }
public MyType() : this(default(T))
{}
public MyType(T val)
{
Value = val;
}
public override string ToString()
{
return this.Value.ToString();
}
}
static void Main(string[] args)
{
var x = new MyType<int>(1);
Foo(x);
Console.WriteLine(x);//Writes 4
}
private static void Foo(MyType<int> y)
{
y.Value += 1;
var l = new List<MyType<int>>();
l.Add(y);
l[0].Value += 1;//This does affect the value of x devlared in Main
Console.WriteLine(l[0]);//Writes 3
Console.WriteLine(y);//writes 3
Foo2(l);
}
private static void Foo2(List<MyType<int>> l)
{
l[0].Value += 1;
Console.WriteLine(l[0]);//writes 4
}
int, int? and System.Int32 are all struct and thus value types and does not compare to Java's Integer wrapper class which is a reference type.
System.Object class though a reference type can cause issue as boxing creates immutable object. In short, you can't alter a boxed value.
int a = 20;
Object objA = a; //Boxes a value type into a reference type, objA now points to boxed [20]
Object objB = objA; //Both objA & objB points to boxed [20]
objA = 40; //While objB points to boxed [20], objA points to a new boxed [40]
//Thus, it creates another ref type boxing a 40 value integer value type,
//Boxed values are immutable like string and above code does not alter value of previous boxed value [20]
Console.WriteLine($"objA = {objA}, objB={objB}");
//Output: objA = 40, objB=20
What exactly corresponds to Java's Integer is a custom generic wrapper class.
int a = 20;
Wrapper<int> wrapA = new Wrapper<int>(a);
Wrapper<int> wrapB = wrapA; //both wrapA and wrapB are pointing to [20]
wrapA.Value = 40; //Changing actual value which both wrapA and wrapB are pointing to
Console.WriteLine($"wrapA = {wrapA}, wrapB={wrapB}");
//Output: wrapA = 40, wrapB=40
Console.ReadKey();
Implementation of the wrapper class is given below:
public class Wrapper<T> where T : struct
{
public static implicit operator T(Wrapper<T> w)
{
return w.Value;
}
public Wrapper(T t)
{
_t = t;
}
public T Value
{
get
{
return _t;
}
set
{
_t = value;
}
}
public override string ToString()
{
return _t.ToString();
}
private T _t;
}
As pointed out in other answers, C# has a unified type system so everything derives from object. If you need to handle null values then use int? to specify that the integer object can be null.
c# have a integer type called int link is here
https://msdn.microsoft.com/en-us/library/5kzh1b5w.aspx

How to implement a basic pointer

I know here is no pointer in Java. But how do I change a value in the calling scope? For instance, I want to write a function that takes an integer num, set the integer to 0 if it's greater than 21, otherwise do nothing.
In the main, my code is as follow:
int a=34;
KillOver21(a);
System.out.print(a);
I expect an 0.
Java is pass by value, so a copy of the parameter a is sent to the method, so modification to a in the method will not affect the original argument a in main
The max you can do is return int from KillOver21(a) method
int z = KillOver21(a); // This will return 0
System.out.print(z);
But you can achieve something like that with custom objects, say you have a class
class AHolder {
public int a;
}
then you can expect AHolder instance to change
public static void main(String [] args) {
AHolder a = new AHolder();
a.a = 34;
killOver21(a);
System.out.println(a.a);
}
public static void killOver21(AHolder b) {
if(b.a > 21) {
b.a = 0;
}
}
Since in the latter (even if its Pass by Value) , the reference is copied and both reference point to same object. So changes made inside the killOver21 method actually changes the object.
It is simply not possible, Java supports pass by value. int a's value will be copied to the function.
You could use Object instead of primitive where the reference value will be copied to your function by which you can get the actual object and modify it.
Fundamentally impossible in Java, period. int are immutable, and passed by value. You would need to create a mutable int type:
class MutableInt {
private int value;
public MutableInt(int value) { this.value = value; }
public getValue() { return this.value; }
public setValue(int value) { this.value = value; }
}
Then:
void KillOver21(MutableInt m) {
if(m.getValue() > 21) { m.setValue(0); }
}
However, be aware the mutable types that represent concepts that are defined by their value rather than their identity are generally an extremely bad idea. But, this is the only way to achieve what you're trying to achieve. Again, I caution you with the strongest words: what you're doing is a bad idea. You should find another way.
Doc, it hurts when I do this.
Then don't do that!
The simpliest way (quick&dirty) is to put value within an array
int holder[] = new int[]{ a};
KillOver21(holder)
System.out.printf( "value=[%d]", holder[0] );
void KillOver21(int holder[] ) {
holder[0] = 0;
}

How Java "pointers" work?

Lets say this is the C++ code:
void change(int& x){
x++;
}
or
void change2(int* a){
*a++;
}
Both will change the global x, right?
So how can I do something like that in java?
Specifically, I want to point to a Vector object
But since Java has no pointers, I'm not sure what to do.
From searching the internet I saw people saying that Java does that in some other way, but I haven't found any real example.
Thanks for
help!
In Java, instead of pointers you have references to objects. You cannot pass a primitive type by reference, but you can wrap a primitive type inside an object and then pass a reference to that object.
Java provides the type Integer which wraps int, however this type is immutable so you cannot change its value after construction. You could however use MutableInt from Apache Commons:
void change(MutableInt x) {
x.increment();
}
The change to x will be visible to the caller.
Specifically, I want to point to a Vector object
When you write Vector v = ...; you are assigning a reference to a vector to the variable v. A reference in Java is very similar to a pointer. References are in fact implemented internally using pointers.
Java uses pass by value. When you pass a vector to a method, you are actually copying a reference to that vector. It does not clone the vector itself. So passing a reference in Java is very similar to passing a pointer in C++.
With Java you cannot pass primitive types like int by reference, they are passed only by value.
The only things you can do is to find artifices to do that, because instead Objects are passed by reference. Here two examples.
Use an array of single value, like this
int[] value = new int[1];
value[0] = 2;
// call a method
obj.setValue(value);
// and in setValue
public void setValue(int[] value) {
value[0] = 5;
}
Or second approach use an holder class:
public class Holder<T> {
public T value;
public Holder(T value) {
this.value = value;
}
}
// then use it in this way
Holder<Integer> h = new Holder<Integer>(2);
obj.setValue(h);
// and in setValue
public void setValue(Holder<Integer> h) {
h.value = 5;
}
In this case I use an holder class implements with generics but you can have a simple holder too, only for integer. For example:
public class IntHolder {
public int value;
public IntHolder(int value) {
this.value = value;
}
}
Java always passes by value and there are no global variables as in the C++ sense. So if you want to do the same as in C++ you need to return the new value.
Thusly:
public int change(int x) {
return ++x;
// or
// return x + 1;
}
To test it:
int x = 2;
change(x);
System.out.println(x); // returns 2
x = change(x);
System.out.println(x); // returns 3
So it doesn't make any sense to let the method be called change, it is more sensible along the lines of calculateThisInt.
Java does pass objects by value. But as Mark Byers mentions the Integer class is immutable and you could use MutableInt from Apache Commons library. To describe how this works you could implement it yourself for your example:
public class MyInt() {
public int i;
public void setInt(int i) {
this.i = i;
}
public int getInt() {
return this.i;
}
public int increment() {
this.i++;
}
}
You need to change your change function to have the above MyInt object as argument:
public void change(MyInt i) {
i.increment();
}
Usage:
MyInt x = new MyInt();
x.setInt(2);
change(x);
System.out.println(x.getInt); // returns 3
In your case you want to change a Vector object...
public void changeVector(Vector v) {
// anything you do with 'v' will change it even
// for the scope that called this method
}
// Usage:
Vector v = new Vector();
changeVector(v);
// v should be changed after calling change vector method
Hope this all makes sense.
Both will change the global x, right?
So how can I do something like that in java? Specifically, I want to
point to a Vector object
The question is somewhat vague, but I got the impression that you ultimately want a global Vector that you can keep stuff in?
Many ways to do that, but one of the simplest is to have a static field in a class, with public static methods for accessing it. (Or simply a public static field which is accessed directly, but that really wouldn't be idiomatic in Java.)
public class Foo {
private static List<Integer> globalVector = new Vector<Integer>();
public static void add(int number){
globalVector.add(number);
}
// ... plus whatever other accessors to the global list that you need
}
Anywhere else in code:
Foo.add(23); // modifies the global vector
(Btw, Vector is kinda obsolete, and typically we'd use ArrayList in its place now. As the Javadoc says, it's been retrofitted to implement the List interface, which I also used in the example.)
While you can't replace an object that's been passed to a function, you can change its state by altering fields directly or calling methods. If you need something like a pointer to a primitive, wrap it in an object. To follow your code, you could do this:
public class IntPointer {
public int value;
public IntPointer(int value) {
this.value = value;
}
}
Then elsewhere you could say:
public static void change(IntPointer ipoint) {
ipoint.value++;
}
public static void main(String[] args) {
IntPointer a = new IntPointer(10);
change(a);
}
This might seem a bit awkward, but it hasn't come up for me as often as you'd think. I'd be more likely to do something like this:
public class ABPair {
private int a = 0;
private int b = 0;
public static void changeA() {
a++;
}
public static void changeB() {
b++;
}
}
So that elsewhere I can say:
public static void main(String[] args) {
ABPair ab = new ABPair();
if (ACondition) {
ab.changeA();
}
}
In other words, my data tends to already be wrapped in some sort of object, and I tend to use the data object's methods to mediate any changes.
Java supports what it calls "references". References act alot like pointers in C/C++-like languages. They don't act the same way "references" work in those languages.
The major differences between a pointer in C and a reference in Java are:
You can't do pointer arithmetic in Java (i.e. you can't "add" or "subtract" from a Java reference, you can only dereference it or compare it with another one).
You can't cast it to an incompatible type: Java is strongly type-safe, you can't "re-interpret" the bytes in memory as some other object.
For some uses of pointers this has no real effect (for example linked lists work pretty much the same in both languages), for others the difference is quite major (arrays in C are just fancy pointer arithmetic, in Java they work quite differently).
So in a way Java references could be called "restricted pointers".

Categories