Reading many kinds of numbers from a byte buffer I've been trying to find a way to collapse all these methods into one. 

Current I have these methods

default byte readByte(long address) {
    return read(address, 1).get();
}

default int readShort(long address) {
    return read(address, 2).getShort();
}

default int readInt(long address) {
    return read(address, 4).getInt();
}

default long readLong(long address) {
    return read(address, 8).getLong();
}

default float readFloat(long address) {
    return read(address, 4).getFloat();
}

default double readDouble(long address) {
    return read(address, 8).getDouble();
}


They are used to read a certain amount of bytes of a memory address (ex 8 bytes for long, 4 for int, 2 for short, etc).

I find using the multiple methods is not very pleasing to look at. 

In theory I'd like a solution similar to something like this:


default &lt;T&gt; T read(long address) {
  if (T instanceof Long) {

      return read(address, 8).getLong();
  } else if (T instanceof Integer) {

      return read(address, 4).getInt();
  } else if (T instanceof Short) {

      return read(address, 2).getShort();
  } else if (T instanceof Byte) {

      return read(address, 1).get();
  } else if (T instanceof Double) {

      return read(address, 8).getDouble();
  } else if (T instanceof Float) {

      return read(address, 4).getFloat();
  } else if (T instanceof Boolean) {

      return read(address, 1).get() == 1;
  }

  throw new RuntimeException("Unknown generic type!");
}



But I don't think that is possible due to the limitation of Java generics.

Can you think of a better/less redundant solution?
There is only ONE problem that will be hard to eliminate because I assert that "ByteBuffer" is not within your domain. And this problem is not related to redundancy in the manner of duplicate code. The bytes read can be derived from the method called:

read(address, 4).getInt();

So if you have any possibility to use "4" within "getInt()" then your code improves a little bit. Maybe extract the magic numbers as constants.

Everything else you assume is of an error type 2. Assuming redundancy where there is not redundancy and acting unnecessarily. So everything you do to the code trying to eliminate redundancy will introduce problems.

For example:

Your generic suggestion will divide responsibility into half. The caller has to synchronize the expected return type with the called method. In the original solution there is no necessity to care.

Leave the code presented as it is. There is no possibility to improve it in the way you expect it.