Can I pass a primitive type by reference in Java?

44,202

Solution 1

While Java supports overloading, all parameters are passed by value, i.e. assigning a method argument is not visible to the caller.

From your code snippet, you are trying to return a value of different types. Since return types are not part of a method's signature, you can not overload with different return types. Therefore, the usual approach is:

int getIntValue() { ... }
byte getByteValue() { ... }

If this is actually a conversion, the standard naming is

int toInt() { ...}
byte toByte() { ... }

Solution 2

Java is always pass-by-value. There is no pass-by-reference in Java. It's written in the specs!

Solution 3

You can't. In Java parameters are always passed by value. If the parameter is a reference type, the reference is passed by value and you can modify it inside the method while with primitive types this is not possible.

You will need to create a wrapper type.

Solution 4

I would say the alternative strategy, if you want to work with primitives, is to do what the Java Libraries do. Just suck it up and have multiple methods.

For example, ObjectInputStream has readDouble(), readByte(), etc.

You're not gaining anything by sharing an implementation of the function, and the clients of your function aren't gaining anything by the variants of your function all having the same name.

UPDATE

Considering your update, I don't think it's necessary to duplicate too much code. It depends on your encoding strategy but I would imagine you could do something like this:

private byte get8Bits();
public byte getByte() {
    return get8Bits();
}
public int getInt() {
    return (get8Bits() << 24) | (get8Bits() << 16) | (get8Bits() << 8) | get8Bits();
}

Anything that shares code more than that is probably over-engineering.

An alternative could be

private long getBits(int numBits);

public byte getByte() {
    return (byte)getBits(8);
}

public int getInt() {
    return (int)getBits(32);
}

i.e. I don't think it makes sense to expose the users of your library to anything other than the primitive types themselves.

If you really, really wanted to then you could make a single method for access like this:

@SuppressWarnings("unchecked")
public static <T> T getValue(Class<T> clazz) {
    if ( clazz == byte.class ) {
        return (T)Byte.valueOf((byte)getBits(8));
    } else if ( clazz == int.class ) {
        return (T)Integer.valueOf((int)getBits(32));
    }
    throw new UnsupportedOperationException(clazz.toString());
}

//...
byte b = getValue(byte.class);
int i = getValue(int.class);

But I fail to see how it's any less cumbersome for clients of your library.

Solution 5

Yes, please be more specific about what you want to achieve. From your description I suggest you have a look at Java generics where you could write something like this:

class SomeClass <GenericType> {
  GenericType val;  

  void setValue(GenericType val) {
     this.val = val;
  }

  GenericType getValue() {
     return val;
  }

  public static void main(String[] args) {
    SomeClass<Integer> myObj = new SomeClass<Integer>();
    myObj.setValue(5);
    System.out.println(myObj.getValue());

    SomeClass<String> myObj2 = new SomeClass<String>();
    myObj2.setValue("hello?!");
    System.out.println(myObj2.getValue());

  }

}
Share:
44,202
Hristo
Author by

Hristo

LinkedIn JustBeamIt

Updated on April 25, 2020

Comments

  • Hristo
    Hristo about 4 years

    I would like to call a method which could potentially take on different versions, i.e. the same method for input parameters that are of type:

    • boolean
    • byte
    • short
    • int
    • long

    The way I would like to do this is by "overloading" the method (I think that is the correct term?):

    public void getValue(byte theByte) {...}
    public void getValue(short theShort) {...}
    ... etc ...
    

    ... but that would mean that I would have to pass the primitive type in by reference... similar to C++ where the method has external effect, where it can modify the variable outside its scope.

    Is there a way to do this without creating new classes or using the Object versions of the primitive types? If not, any suggestions on alternative strategies?

    Let me know if I should further explain to clear up any confusion.


    UPDATE

    What I'm actually trying to do is construct the primitive type from a set of bits. So if I'm dealing with the byte version of the method, I want to pretty much do my work to get 8 bits and return the byte (since I can't pass by reference).

    The reason I'm asking this question is because the work I do with bits is very repetitive and I don't want to have the same code in different methods. So I want to find a way for my ONE method to KNOW how many bits I'm talking about... if I'm working with a byte, then 8 bits, if I'm working with a short, 16 bits, etc...

  • Hristo
    Hristo over 13 years
    Okay :( How would I create this "wrapper type"? Can you show me some code?
  • Robert Munteanu
    Robert Munteanu over 13 years
    The be pedantic, it's pass by value of reference. You get the same object ( for non-primitives ) but you're unable to change the actual reference outside of your own scope.
  • aperkins
    aperkins over 13 years
    A wrapper type is an object that contains the value you want changed. They are often used to bring together related values in a single object that can be passed around more easily.
  • Darin Dimitrov
    Darin Dimitrov over 13 years
    @Hristo, you could create a class which will hold the primitive type and pass this class to the method.
  • Hristo
    Hristo over 13 years
    Yes, I understand this. Any alternatives?
  • Hristo
    Hristo over 13 years
    hmmm... ok. I'll take a look into this. Thanks
  • Mark Peters
    Mark Peters over 13 years
    +1 yeah beat me to it. Looks like the OP's goal is to avoid this, when it's a perfectly common and legitimate pattern.
  • Hristo
    Hristo over 13 years
    I added an UPDATE to my post. Please refer to it for more information.
  • Hristo
    Hristo over 13 years
    hahaha... fair enough. If I don't find a solution that makes me happy, I'll go with the multiple methods.
  • Hristo
    Hristo over 13 years
    Refer to my UPDATE as to why I'm trying to avoid this. It seems to me now that I'll just end up doing it this way, but it was worth asking.
  • meriton
    meriton over 13 years
    Yes, even reading your update I would recommend my approach. Callers have to somehow specify the number of bits they want, and spelling it out in the method name is pretty clear.
  • Hristo
    Hristo over 13 years
    Fair enough. Thanks for your suggestions!
  • whiskeysierra
    whiskeysierra over 13 years
    The usage of such wrapper times feels like using AtomicBoolean, AtomicInteger, etc. Without the concurrency/blocking overhead of course.
  • Hristo
    Hristo over 13 years
    Actually... this is not a bad idea... but I'll be using an InputStream. Nevertheless, this is an interesting suggestion. Thanks.
  • romacafe
    romacafe over 13 years
    Well if you're using InputStream, then its even easier! You just pass it to your various functions and read as many bytes as you need. Your position in the stream moves forward each time you call a function, by as many bytes as required by that function. Easy as pie!
  • Mickael Bergeron Néron
    Mickael Bergeron Néron about 7 years
    What programmer would read the specs instead of going to SO? It is way faster to go to SO for an answer to such a question than going through the specs. If a programmer would rather go through the specs for such a question, that programmer is pretty inefficient.
  • Shivku
    Shivku about 4 years
    @whiskeysierra So boxed classes? Like Integer.