Can I pass a primitive type by reference in Java?

后端 未结 9 1746
粉色の甜心
粉色の甜心 2021-02-05 22:58

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
相关标签:
9条回答
  • 2021-02-05 23:28

    The object types of primitive types in Java (Double, Integer, Boolean, etc) are, if I remember correctly, immutable. This means that you cannot change the original value inside a method they are passed into.

    There are two solutions to this. One is to make a wrapper type that holds the value. If all you are attempting to do is change the value or get a calculation from the value, you could have the method return the result for you. To take your examples:

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

    And you would call them by the following:

    Short s = 0;
    s = foo.getValue(s);
    

    or something similar. This allows you to mutate or change the value, and return the mutated value, which would allow something like the following:

    Short s = foo.getValue(10);
    

    Hope that helps.

    0 讨论(0)
  • 2021-02-05 23:28

    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.

    0 讨论(0)
  • 2021-02-05 23:31

    Only by creating your own value holding types.

    0 讨论(0)
提交回复
热议问题