Based on java.util.concurrent.TimeUnit class I wrote similar class to convert size units:public enum ByteUnit {  BYTES(B) {    @Override    public long toBytes(long value) {      return value;    }    @Override    public long toKiB(long value) {      return value / KIBI;    }    @Override    public long toMiB(long value) {      return value / MIBI;    }    @Override    public long toGiB(long value) {      return value / GIBI;    }    @Override    public long convert(long value, @NotNull ByteUnit unit) {      return unit.toBytes(value);    }  },  KIBIBYTES(KiB) {    @Override    public long toBytes(long value) {      return safeTo(value, KIBI);    }    @Override    public long toKiB(long value) {      return value;    }    @Override    public long toMiB(long value) {      return value / (MIBI / KIBI);    }    @Override    public long toGiB(long value) {      return value / (GIBI / KIBI);    }    @Override    public long convert(long value, @NotNull ByteUnit unit) {      return unit.toKiB(value);    }  },  MEBIBYTES(MiB) {    @Override    public long toBytes(long value) {      return safeTo(value, MIBI);    }    @Override    public long toKiB(long value) {      return safeTo(value, MIBI / KIBI);    }    @Override    public long toMiB(long value) {      return value;    }    @Override    public long toGiB(long value) {      return value / (GIBI / MIBI);    }    @Override    public long convert(long value, @NotNull ByteUnit unit) {      return unit.toMiB(value);    }  },  GIBIBYTES(GiB) {    @Override    public long toBytes(long value) {      return safeTo(value, GIBI);    }    @Override    public long toKiB(long value) {      return safeTo(value, GIBI / KIBI);    }    @Override    public long toMiB(long value) {      return safeTo(value, GIBI / MIBI);    }    @Override    public long toGiB(long value) {      return value;    }    @Override    public long convert(long value, @NotNull ByteUnit unit) {      return unit.toGiB(value);    }  };  private static final long KIBI = 1024L;  private static final long MIBI = KIBI * 1024L;  private static final long GIBI = MIBI * 1024L;  @NotNull  private final String name;  private ByteUnit(@NotNull String name) {    this.name = name;  }  public abstract long convert(long sourceValue, @NotNull ByteUnit sourceUnit);  public abstract long toBytes(long value);  public abstract long toKiB(long value);  public abstract long toMiB(long value);  public abstract long toGiB(long value);  @Override  public String toString() {    return name;  }  private static long safeTo(long value, long multiplier) {    final long overflow = Long.MAX_VALUE / multiplier;    if (value > overflow) {      return Long.MAX_VALUE;    }    if (value < -overflow) {      return Long.MIN_VALUE;    }    return value * multiplier;  }}But I don't realy like the design. I think there are two ways to improve it:Use from instead of to. Main disadvantage is that it differs from TimeUnit style. Usage will look like:ByteUnit.KIBIBYTES.fromMiB(42)Create intermediate object of class, which has all the methods of converting (leads to excess allocation on each call):ByteUnit.mebibytes(42).toBytes()Have anyone any suggestions?
ByteUnit class to convert across size units
java;converting;enum