Question

I have the below hierarchy of classes which just implement the imaginery functionality of encoding and decoding the animals from the given bytearrays.

public abstract class Animal {
}

class Tiger extends Animal{
    private String name;

    public void setName() { 
    }

    public String getName() {
        return this.name;
    }
}

abstract class AnimalTransformer {
    public static <T> T decodeAnimalFromBytes(byte[] animalInBytes) {
        return null;
    }

    public static byte[] encodeAnimalInBytes(Animal animal) {
        return null;
    }

}

class TigerTransformer extends AnimalTransformer{
    public static Tiger decodeAnimalFromBytes(byte[] animalInBytes) {
        return new Tiger();
    }

    public static byte[] encodeAnimalinBytes(Tiger tiger) {
        return new byte[0];
    }
}

On overriding method from the AnimalTransformer abstract class in the TigerTransformer class which extends AnimalTransformer , i get the following warning

Type safety: The return type Tiger for decodeAnimalFromBytes(byte[]) from the type 
TigerTransformer needs unchecked conversion to conform to T 
from the type AnimalTransformer

I understand the cause of this warning but unfortunately i am not able to solve it as i am new to generics. Can someone briefly explain how can this warning be remedied?

Was it helpful?

Solution 2

First of all, don't try to 'override' with static methods. It does not work the way you think it does - the 'overridden' static methods can still be accessed from the subclass in devious (accidental) ways. If you want overriding behavior, use local methods.

The warning is being generated because the Tiger method signature is not compatible with what the super-class method promises - that any class <T> chosen by the client can be decoded to, which is a very big, unfulfillable promise.

A better method would be:

abstract class AnimalTransformer<T extends Animal> {
  public T decodeAnimalFromBytes(byte[] animalInBytes) {
    return null;
  }
  public static byte[] encodeAnimalInBytes(T animal) {
    return null;
  }
}

class TigerTransformer extends AnimalTransformer<Tiger> {
  public Tiger decodeAnimalFromBytes(byte[] animalInBytes) {
    return new Tiger();
  }
  public byte[] encodeAnimalinBytes(Tiger tiger) {
      return new byte[0];
  }
}

This represents what you are trying to model more clearly - an AnimalTransformer provides transformation methods for some subclass of Animal, and it is up to the subclass, or anonymous implementation, to clarify which.

OTHER TIPS

Note that there's no use in making the methods of AnimalTransformer static. Static methods don't override each other by inheritance. Furthermore, you are not binding the data type the transformer works on to the type of the decoded object (e.g., TigerTransformer can return Horse objects).

I would do the following instead, which I consider to be more type safe:

abstract class AnimalTransformer <T> {
    public abstract T decodeAnimalFromBytes(byte[] animalInBytes);

    public abstract byte[] encodeAnimalInBytes(T animal);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top