Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

181
Visualizações
Class hierarchy problem with java generics

I have run into a problem with class hierarchy in a generic function. I need to enforce that, with the two classes T and U specified in the function, one is the child of the other. I have found to much surprise that the construct <T extends U> does not at all enforce a parent child relation of U and T. Instead it also allows T and U to be the same type.

This creates a problem because it looks like in a case where U extends T Java will not indicate the error but instead it will happily deduce both objects to be of type T (which is true no doubt) and then compile and run the code without any complaint.

Here is an example that illustrates the issue:

public class MyClass {
    public static void main(String args[]) {
      Foo foo = new Foo();
      Bar bar = new Bar();

      // This code is written as intended
      System.out.println( justTesting(foo, bar) );

      // This line shouldn't even compile
      System.out.println( justTesting(bar, foo) );
    }
    
    static interface IF {
       String get(); 
    }
    
    static class Foo implements IF {
       public String get(){return "foo";} 
    }
    
    static class Bar extends Foo {
        public String get(){return "bar";}
        
    }
    
    static <G extends IF , H extends G> String justTesting(G g, H h) {
        if (h instanceof G)
            return h.get() + " (" + h.getClass() + ") is instance of " + g.getClass() + ". ";
        else
            return "it is the other way round!";
    }
}

And this is the output:

bar (class MyClass$Bar) is instance of class MyClass$Foo. 
foo (class MyClass$Foo) is instance of class MyClass$Bar. 

I need to ensure that the parent child relation of the generic classes is observed by the compiler. Is there any way to do that?

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

It compiles, because IF is a "upper bound" for both H and G.

Means: Generics are not that "dynamic" as we think, and we could also write:

static <G extends IF, H extends IF> ... // just pointing out that G *could* differ from H 

Disregarding null check, is this, what you want:

  static <G extends IF, H extends G> String justTesting(G g, H h) {
    if (g.getClass().isAssignableFrom(h.getClass())) {
      return h.get() + " (" + h.getClass() + ") is instance of " + g.getClass() + ". ";
    } else {
      return "it is the other way round!";
    }
  }

?

Class.isAssignableFrom()


Prints:

bar (class com.example.test.generics.Main$Bar) is instance of class com.example.test.generics.Main$Foo. 
it is the other way round!

And watch out with "anonymous classes", e.g.:

System.out.println(
  justTesting(
    new IF() {
      @Override
      public String get() {
        return "haha";
      }
    }, foo)
);

System.out.println(
  justTesting(
    foo, new IF() {
      @Override
      public String get() {
        return "haha";
      }
    }
  )
);

print both "it is the other way round!", so the decision here is not that "binary".

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda