4

I have an interface (p) and an implementation (imp). If I do the following in the code, then the check works:

if (!(imp instanceof p)) {
   logger.error(imp.getClass().getName()+ 
    " doesn't satisfy the interface "
   +p.getClass().getName());
   }

I tried to make it into a callable method as follows:

private boolean checkInterfaceImplementation(Object implemen, Object inter){
    return (implemen instanceof inter);
}

which failed.

Then I found that inter needs to be a specific type and I cannot use a generic object. Then I found out about

"B.class.isAssignableFrom(A.getClass())"

Then I did:

System.out.println("B.class.isAssignableFrom(A
                    .getClass())");

The output was

true

I read up more from this question. My question is "Is this (the second implementation with ".isAssignableFrom") the preferred or standard way to implement said method? Is there any way that this present implementation can create problems?

Community
  • 1
  • 1
FirstName LastName
  • 1,891
  • 5
  • 23
  • 37
  • 5
    Generally use of `instaceof` and `isAssignableFrom` indicates code smell. Try and use polymorphism to your advantage rather than checking types. – Boris the Spider May 15 '14 at 18:08
  • 1
    Your method takes two objects as parameters. But then your code uses a hard-coded class literal (B.class). So why don't you use `gzipCompressor instanceof B`? – JB Nizet May 15 '14 at 18:11
  • 1
    Also, note that `(someCondition) ? true : false` can just be written as `someCondition`, which is always preferable. So in your second code snippet, just `return (implemen instanceof inter)` (that still fails, for the same reason -- but that sort of style is always better). After all you, wouldn't test `if (i == 0)` using `if( (i == 0) == true)`, right? It's similarly redundant. – yshavit May 15 '14 at 18:26
  • @JBNizet: Modified the code to make it consistent with the A & B notation. Also, I wanted to make it a util method so it could be used by other developers, since the method "CheckInterfaceImplementation(obj imple, obj inter)" would be used as a black box by other developers in their code. – FirstName LastName May 15 '14 at 19:06
  • @BoristheSpider: The implementation implements the interface. I just wanted to put a check in place, so that in the future is someone uses another B class, I ensure that they have used the interface. What would be your suggestion to do instead of doing what I am doing? – FirstName LastName May 15 '14 at 19:12
  • 1
    Also, whoever gave the 1 vote for the question to be closed, it would be great if you also commented why you think the question should be closed and I can see if I can alleviate your concerns and improve the question. It is more helpful for the community. – FirstName LastName May 15 '14 at 19:13
  • What's wrong with just using the interface in the method signature? – Boris the Spider May 15 '14 at 19:15
  • That would make the "CheckInterfaceImplementation" interface dependent. I was wondering if there is an easier way to make it pluggable. But judging from the answers, I might be trying to beat a dead horse when using an instanceOf when required will work. – FirstName LastName May 15 '14 at 19:34

2 Answers2

2

It's hard to understand your question. I will edit when more details are received, if necessary, but as a general rule of thumb instanceof is an indicator of a lack of polymorphism and a design issue. Not always the case, but if you are a beginner I would try to use it as little as possible.

Instead, consider why that check is even there. If "imp" implements "p", then you are guaranteeing that any "imp" will have all the methods in "p". If it doesn't, you will receive a compiler error before you can even build. This is very abstract right now so I will do quick example.

public interface Runs {
     public void run();
}

public class Cat implements Runs {
     int numLegs;
     public Cat() {
          this.numLegs = 4;
     }
     public void run() {
          System.out.println("does whatever running cats do");
     }
}

public class Human implements Runs {
     int numLegs;
     public Human() {
          this.numLegs = 2;
     }
     public void run() {
          System.out.println("does whatever running humans do");
     }
}
 public class Main {
         public static void main(String[] args) {
              Cat cat = new Cat();
              Human human = new Human();

              ArrayList<Runs> listOfRunners = new ArrayList<Runs>();
              listOfRunners.add(cat);
              listOfRunners.add(human);
              Runs runner = listOfRunners.get(0);
              /* no compiler error because by implementing Runs we guarantee it has run() method */
              runner.run();
              runner = listOfRunners.get(1);
              /* It doesn't matter what the object is. We don't care if it is cat or human */
              runner.run();
         }
    }
Andrew Campbell
  • 17,665
  • 2
  • 16
  • 25
1

Not sure exactly what you are trying to do, but something like this should work:

inter.getClass().isInstance(implemen)

Most likely what you are trying to do can be done in a much better way than resorting to this, though.

Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205