Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make Java consider the most specific type when choosing method among overloaded methods

I would like to perform several operations based on the type of an object and without using instanceof. At first I was thinking of overloading methods based on types (as seen below), and thought that maybe Java would choose the method appropriately (based on most specific class of object).

import java.util.ArrayList;
import java.util.List;


public class TestA {

    public static void main(String[] args)
    {
        List<Object> list = new ArrayList();
        list.add(new A());
        list.add(new B());
        list.add(new C());
        list.add(new Object());

        TestA tester = new TestA();

        for(Object o: list)
        {
            tester.print(o);
        }
    }

    private void print(A o)
    {
        System.out.println("A");
    }

    private void print(B o)
    {
        System.out.println("B");
    }

    private void print(C o)
    {
        System.out.println("C");
    }

    private void print(Object o)
    {
        System.out.println("Object");
    }
}

class A {

}

class B extends A {

}

class C {

}

The output is:

Object
Object
Object
Object

However the output I'm after is:

A
B
C
Object
  • Is there a way to make Java choose the method based on the most specific type of the parameter object?
  • If not, what alternatives can I look at for such functionality, without the aid of instanceof
  • I was actually trying to simulate the visitor pattern however it seems, what makes visitor pattern work is because of the double dispatch, which makes the parameter being "accepted" be in the correct type during function call, particularly, visitor.accept(this) in class A causes the function visitor.accept(A o) be called.
  • I'm honestly against instanceof because I've read using it is bad practice; in this case, would it still be bad practice?
like image 703
Chad Avatar asked Aug 09 '13 14:08

Chad


People also ask

Which methods can be overloaded in Java?

Java supports method overloading through two mechanisms: By changing the number of parameters. By changing the data type of parameters Overloading by changing the number of parameters A method can be overloaded by changing the number of parameters.

Can overloaded methods have different data types?

No, you cannot overload a method based on different return type but same argument type and number in java.


2 Answers

Well my answer would be to make classes A,B and C implement a common interface.

And then each of them can have their own specific implementations of this interface.

This way, you can call the same method for all the objects(thus avoiding overloaded methods), and also ensure custom functionality based on the type of the object(i.e the class from which it was instantiated).

like image 165
kkaosninja Avatar answered Dec 31 '22 03:12

kkaosninja


This answer considers that modifying given classes and their relationship is not an option.

Is there a way to make Java choose the method based on the most specific type of the parameter object?

Java compiler cannot cast this for you because maybe that's not what you want (in your case that's what you want, but maybe other people don't want this behavior and they would be no solution for them). Since you're passing an Object reference to print(), the compiler will call print(Object).

If not, what alternatives can I look at for such functionality, without the aid of instanceof

You can wrap your Object with its type in a wrapper class, e.g.:

public class ObjectWrapper {
    private final Object object;
    private final int type;
}

This way you can safely cast to the type of the Object without using instanceof. Although this IMHO is more complicated than simply using instanceof, and actually it only creates your own instanceof...

I'm honestly against instanceof because I've read using it is bad practice; in this case, would it still be bad practice?

In programming, nothing is always a bad practice. Everything depends on the situation. In this situation I think you can use instanceof and do unsafe casting because the design requires so. And anyway, if instanceof operator exists in the language, is because it's used. If instanceof was always a bad practice, it wouldn't exist as part of the language. See this and this.

I was actually trying to simulate the visitor pattern however it seems, what makes visitor pattern work is because of the double dispatch, which makes the parameter being "accepted" be in the correct type during function call, particularly, visitor.accept(this) in class A causes the function visitor.accept(A o) be called.

Check my second link for cons on using the visitor pattern.

like image 38
m0skit0 Avatar answered Dec 31 '22 05:12

m0skit0