1

I have 2 classes e.g. A and B.
These classes have a couple of getter/setter methods with the same name.

Now in the code I do the following:

if(obj.getClassName().equals(A.class.getName())){
   A a = (A) obj;
   String result = a.getInfo();
}
else if(obj.getClassName().equals(B.class.getName())){
   B a = (B) obj;
   String result = a.getInfo();
}

I was wondering if there is a way to call the getInfo avoiding the if statements.
Note: I can not refactor the classes to use inheritence or something else.
I was just interested if there is a trick in java to avoid the if statements.

7
  • Yes I know instanceof.I was wondering if I could avoid trying to detect the class altogether Commented Oct 19, 2011 at 6:34
  • The obj is send as part of method params from a remote call as generic objects Commented Oct 19, 2011 at 6:36
  • @Luchian:Could be either A or B or null or neither Commented Oct 19, 2011 at 6:37
  • @LuchianGrigore: Object type since there is no super common class. Commented Oct 19, 2011 at 6:37
  • @user384706: Generic object? type??? Commented Oct 19, 2011 at 6:38

8 Answers 8

6

Unless you want to use reflection, no. Java treats two types which happen to declare the same method (getInfo()) as entirely separate, with entirely separate methods.

If you've got commonality, you should be using a common superclass or a common interface that both of them inherit. You've tagged the question "design-patterns" - the pattern is to use the tools that the language provides to show commonality.

As Eng.Fouad shows, using instanceof is simpler anyway - and better, as it means your code will still work with subclasses of A or B.

You can isolate this ugliness, of course, by putting it in a single place - either with a facade class which can be constructed from either an A or a B, or by having a single method which performs this check, and then calling that from multiple places.

Sign up to request clarification or add additional context in comments.

4 Comments

Would you like to answer this as well: stackoverflow.com/questions/7811687/… People are waiting for your answer
@djaqeel: If folks are waiting for my answer on a C++ question, they'll be waiting for a long time :)
You are funny as well... But I think the question is general one, not specifically a C++ question.
@djaqeel: No, it's a terminology question, and the subtleties and nuances between different languages are significant.
1

If you can't use inheritance and want to avoid if statements (even using instanceof)... well... the best you can do is wrap the check, cast and call in a function to avoid code duplication... otherwise there's no way to do this.

Comments

1

You need reflection. here is my complete example.

Class A

 package a;
    public class A {
        String info;
        public String getInfo() {
            System.out.println("A getInfo");
            return info;
        }
        public void setInfo(String info) {
            this.info = info;
        }
    }

Class B

package a;
public class B {
    String info;
    public String getInfo() {
        System.out.println("B getInfo");
        return info;
    }
    public void setInfo(String info) {
        this.info = info;
    }
}

Test Class

package a;
import java.lang.reflect.Method;
public class TestAB {
    public static void main(String[] args) {
        A a= new A();
        doSth(a);
    }
    private static void doSth(Object obj) {
        Class c = obj.getClass();
        Method m;
        try {
            m = c.getMethod("getInfo", new Class[] { });
            String result = (String) m.invoke(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

See this line :

Class c = obj.getClass();

and

m = c.getMethod("getInfo", new Class[] { });

and

String result = (String) m.invoke(obj);

There is no if statements

Comments

1

If obj is declared as either A or B, you can use overloaded methods. (A good argument for type safety.) Here's a test that illustrates this:

import static org.junit.Assert.*;

import org.junit.Test;

public class FooTest {

    class A {
        public String getInfo() {
            return "A";
        }
    }

    class B {
        public String getInfo() {
            return "B";
        }
    }

    public String doBarFor(A a) {
        return a.getInfo();
    }

    public String doBarFor(B b) {
        return b.getInfo();
    }

    public String doBarFor(Object obj) {
        throw new UnsupportedOperationException();
    }

    @Test
    public void shouldDoBarForA() {
        A a = new A();
        assertEquals("A", doBarFor(a));
    }

    @Test
    public void shouldDoBarForB() {
        B b = new B();
        assertEquals("B", doBarFor(b));
    }

    @Test(expected = UnsupportedOperationException.class)
    public void shouldFailIfDeclaredAsObject() {
        Object a = new A();
        assertEquals("A", doBarFor(a)); // exception thrown
    }
}

Comments

0

How about:

String result = null;

if(obj instanceof A)
{
    result = ((A) obj).getInfo();
}
else if(obj instanceof B)
{
    result = ((B) obj).getInfo();
}

2 Comments

Yes I know instanceof.I was wondering if I could avoid trying to detect the class altogether
Beware of instanceof operator javapractices.com/topic/TopicAction.do?Id=31
0

Refer to : this tutorial if this is what you were trying to achieve.

Comments

0

If obj is an Object, you'll need to check. If you don't want to use an if-statement, you can try just casting and catch the exception:

String result = null;
try {
    result = ((A)obj).getInfo();
}
catch(ClassCastException e1) {
    try {
        result = ((B)obj).getInfo();
    }
    catch(ClassCastException e2) {
         // do something else
    }
}

Another thing you can do is make both classes implement an Interface then check for just that Interface, something like:

public interface HasInfo
{
    public String getInfo();
}

Then add implements HasInfo in the class definition for A and B. Then you can just check (or cast) to HasInfo.

Comments

0

In Java you can use a dot as a scope resolution operator with static methods. Try something like this:

String a_info = A.getInfo();
String b_info = B.getInfo();

With objects, if two interfaces really have the same method with the same parameters and the same return type, why must they be treated differently? Take a look here for some more insight into the problem.

Good luck.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.