0
\$\begingroup\$

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 <T> 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?

\$\endgroup\$
  • \$\begingroup\$ What is the return value of the read(address, xxx) calls ? \$\endgroup\$ – Simon Forsberg Jan 2 '16 at 12:37
  • \$\begingroup\$ How do you call these readLong, readShort methods? How are they used in your code? \$\endgroup\$ – Simon Forsberg Jan 2 '16 at 12:38
  • \$\begingroup\$ @SimonForsbergMcFeely read(address, xxx) returns a ByteBuffer. The methods are called via the Process class. Eg: int hi = process.readInt(100). \$\endgroup\$ – Jonathan Beaudoin Jan 2 '16 at 12:41
  • 1
    \$\begingroup\$ The point is, that you should know yourself, which data type you want to read next. So what will be a benefit out of a generic solution? \$\endgroup\$ – bobbel Jan 2 '16 at 12:42
  • \$\begingroup\$ I see that the methods are specified as default methods in an interface, what is the rest of the interface? \$\endgroup\$ – Simon Forsberg Jan 2 '16 at 23:16
3
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.