1

I have an interface like this:

public interface Byteable<T> {
    byte[] toBytes();
    T fromBytes(byte[] bytes);
}

which, like the name implies, transforms an object to a byte pattern and can recreate an object from a given byte-array (or throw some kind of exception if not). I like the toBytes() method and it must be non-static, because it can only be applied to objects. But how can I create a static method so that I can call

ClassName.fromBytes(...);

How can I ensure, that every class implementing the interface has both of those functions or how can I create a static method that uses the non-static fromBytes(...)? Is it good practice to create a default constructor and the do something like

new ClassName().fromBytes();

Is there any good practice? I guess an abstract class isn't a solution either, because it can not have static methods, can it?

F_Schmidt
  • 508
  • 3
  • 19
  • 1
    You can not enforce the presence of a `static` method in implementations, but why does it matter? When you want a `static` `fromBytes` method in `ClassName`, you have to declare the method in `ClassName` anyway, whether mandated by the interface or not. To the caller performing `ClassName.fromBytes(...);`, it makes no difference whether an interface declares the method or not. – Holger Jun 18 '20 at 14:15

2 Answers2

2

you can create an abstract class that will contain your both method as abstract and you will extend that abstract class in your desired class.

    public abstract class Byteable<T> {
      abstract byte[] toBytes();
      abstract T fromBytes(byte[] bytes); 
    }

   public YourClass extends Byteable<YourClass>{
     //provide implementation for abstract methods
     public byte[] toBytes(){
        //write your conversion code 
     }
     public YourClass fromBytes(byte[] bytes){
        //write your conversion code 
     }
   }

Now you can create an object of your class and use both the methods.

YourClass obj = new YourClass();
obj.toBytes()
obj.fromBytes(....)

And you can do the same with any desirable class just need to implement or give functionality to class to perform these tasks.

Other than this you can write one generic transform class :

public class Byteable<I,O> {
  O toBytes(I obj){
    // Your transformation code
  }
  T fromBytes(O bytes){
    // Your implementation
  } 
}

Byteable<YourClass,byte[]> transformer = new Byteable<YourClass,byte[]>(); 
transformer.toBytes(new YourClass())
transformer.fromBytes(....);

I hope it's helpful for you.

Nitesh Sharma
  • 433
  • 2
  • 13
1

What you're trying to do is an abstract static method and that isn't allowed in Java. Check this.

Besides that problem you can try this way.

public interface Byteable<T> {
    byte[] toBytes();
    Builder<T> builder();

    interface Builder<T> {
        T fromBytes(byte[] bytes);
    }
}

In this case you need to implement two interface's. An example would be like this.

public class Student implements Byteable<Student> {
    public final String name;

    public Student(String name) {
        this.name = name;
    }

    @Override
    public byte[] toBytes() {
        return name.getBytes();
    }

    @Override
    public Builder<Student> builder() {
        return bytes -> new Student(new String(bytes));
    }

    public static void main(String[] args) {
        Student s1 = new Student("Ana");
        Builder<Student> builder = s1.builder();
        byte[] bytes = s1.toBytes();
        Student s2 = builder.fromBytes(bytes);

        System.out.println(s2.name);    // Outputs Ana
    }
}

Note:

Is there any good practice? I guess an abstract class isn't a solution either, because it can not have static methods, can it?

You can have static methods in an abstract class.

chriptus13
  • 584
  • 5
  • 16