adziri
adziri

Reputation: 311

Java generics return types

for now I have a couple of the same methods like:

default Byte readByte(InputStream stream) {
    ByteBuffer bytes = ByteBuffer.allocate(Byte.BYTES);
    bytes.order(ByteOrder.nativeOrder());
    while (0 != bytes.remaining()) {
        try {
            bytes.put((byte)stream.read());
        }
        catch (Exception e) {
            e.getStackTrace();
        }
    }
    bytes.rewind();
    return bytes.get();
} 
...
default Short readShort(InputStream stream) {
    ByteBuffer bytes = ByteBuffer.allocate(Short.BYTES);
    bytes.order(ByteOrder.nativeOrder());
    while (0 != bytes.remaining()) {
        try {
            bytes.put((byte)stream.read());
        }
        catch (Exception e) {
            e.getStackTrace();
        }
    }
    bytes.rewind();
    return bytes.getShort();
}

and same for Integer, Float, Double and than I think how I can make it more generic?

What I try, for example:

private <T extends Number> T read(InputStream stream) {
    ByteBuffer bytes = ByteBuffer.allocate(T.BYTES);
    bytes.order(ByteOrder.nativeOrder());
    while (0 != bytes.remaining()) {
        bytes.put((byte)stream.read());
    }
    bytes.rewind();
    switch (T.class) {
        case Byte.TYPE:     return bytes.get();
        case Short.TYPE:    return bytes.getShort();
        case Integer.TYPE:  return bytes.getInt();
        case Long.TYPE:     return bytes.getLong();
        case Float.TYPE:    return bytes.getFloat();
        case Double.TYPE:   return bytes.getDouble();
        default:
            throw new UnsupportedTypeException(T.class);
    }
}

So, but it didn't work as I think, Java != C++ ok.. So is there any way to do it in generic style?

Upvotes: 0

Views: 88

Answers (1)

dmitrievanthony
dmitrievanthony

Reputation: 1561

Generics in Java are compile-time, so you can't use them to solve your problem. I would suggest to manually declare methods (getByte(), getShort(), etc), but use some "generic" implementation inside like in the following example:

public Byte readByte(InputStream is) {
    return read(is, Byte.BYTES, ByteBuffer::get);
}

public Short readShort(InputStream is) {
    return read(is, Short.BYTES, ByteBuffer::getShort);
}

// And other methods...

private <T extends Number> T read(InputStream is, int length, Function<ByteBuffer, T> getter) {
    ByteBuffer bytes = ByteBuffer.allocate(length);
    bytes.order(ByteOrder.nativeOrder());
    while (0 != bytes.remaining()) {
        try {
            bytes.put((byte)is.read());
        }
        catch (Exception e) {
            e.getStackTrace();
        }
    }
    bytes.rewind();
    return getter.apply(bytes);
}

In addition to that I would also mention that it looks like you trying to re-implement DataInputStream. This is a InputStream wrapper that already has all methods you need (readByte(), readShort(), etc).

Upvotes: 3

Related Questions