How can I name the most specific method using generics?

Having the following example:

public class Test {

    public static class A {}

    public static void main(String[] args) {
        A a = new A();
        m1(a);
    }

    public static <T> void m1(T t) {
        // t.getClass().getSimpleName() is A
        // t instanceof A is true
        m2(t);
    }

    /* Not called */
    public static void m2(A a) {
        System.out.println("A");
    }

    public static void m2(Object o) {
        // o.getClass().getSimpleName() is A
        // o instanceof A is true
        System.out.println("O");
    }

}

I do not understand why it is m2(A a)chosen instead m2(Object o). As you can see, when called m2(t), tis A.

Output

  • current

    O
    
  • expected

    A
    

How can I use generics for the situation above to choose m2(A a)?


Edit:

I would like to have a general solution that will work even if I add a type B(similar to A).

...
public static void main(String[] args) {
    A a = new A();
    m1(a);
    B b = new B();
    m1(b);
}
...
public static void m2(B b) {
    System.out.println("B");
}
...

Output

  • current

    O
    O
    
  • expected

    A
    B
    
+4
source share
2 answers

You need to do:

public static <T extends A> void m1(T t) {
    m2(t);
}

, m2(A a) m2(Object o).

+4

, Java . , , , :

public class Test {
    public static interface Visitable {
        void accept(Visitor visitor);
    }

    public static class A implements Visitable {
        @Override
        public void accept(Visitor visitor) {
            visitor.visit(this);
        }
    }

    public static class B implements Visitable {
        @Override
        public void accept(Visitor visitor) {
            visitor.visit(this);
        }
    }

    public static interface Visitor {
        void visit(A a);

        void visit(B b);
    }

    public static class PrintingVisitor implements Visitor {
        @Override
        public void visit(A a) {
            System.out.println("A");
        }

        @Override
        public void visit(B b) {
            System.out.println("B");
        }
    }

    public static void main(String[] args) {
        Visitable visitable = new A();
        m(visitable);
        visitable = new B();
        m(visitable);
    }

    public static void m(Visitable visitable) {
        visitable.accept(new PrintingVisitor());
    }
}
+3

Source: https://habr.com/ru/post/1584002/


All Articles