22

My method gets Class as a parameter and I have to check that one my variables is of type class.

Volvo v1 = new Volvo();
Class aClass = v1.getClass();
check(aClass);

inside I need to do something like

   v2 instanceof aClass  ? "True" : "False");

but this doesn;t compile .

Bick
  • 17,833
  • 52
  • 146
  • 251
  • Shouldn't the compiler be able to check for you? How do you declare your check method? – Hovercraft Full Of Eels Sep 21 '14 at 16:28
  • v2 instanceof **Class** ? "True" : "False"); – Nabin Sep 21 '14 at 16:30
  • 1
    I'm smelling possible anti-pattern use here, and again wonder if using generics to better specify the type of the parameter might be a better and cleaner solution, to allow the problem to be solved at **compile time** not at **run time**. – Hovercraft Full Of Eels Sep 21 '14 at 16:32
  • 1
    I've written an answer with a summary of ways to avoid operations on arguments of the raw Class type. Most of the time, as @HovercraftFullOfEels already mentioned you don't need to do those because Java provides ways to let the compiler do the checking for you. – user268396 Sep 21 '14 at 17:01

4 Answers4

31

I think you want aClass.isInstance( v2 ). The docs say it works the same as the instanceOf keyword. I guess they can't use instanceOf as a method name because keywords can't be used as method names.

v2 = ???
Volvo v1 = new Volvo();
Class aClass = v1.getClass();
aClass.isInstance( v2 )       // "check(aClass)"

Or maybe just use a class literal, if "Volvo" is a constant.

v2 = ???
Volvo.class.isInstance( v2 );
markspace
  • 10,621
  • 3
  • 25
  • 39
19
    Volvo v = new Volvo();
    if (v instanceof Volvo) {
        System.out.println("I'm boxy, but safe.");
    }
cjcdoomed
  • 332
  • 1
  • 4
4

As Hovercraft Full Of Eels mentioned, you can generally avoid such explicit method calls by leaning on the compiler to do the checking for you. Some approaches:

  • You are writing a container of a generically typed thing. Let the type of thing be T, then Java allows you to express this as follows:

    public class MyClass<T> { private T thing; public void setThing(T t) { this.thing = t; } private void check(Class<T> cls) {} // probably not necessary }

    Then create instances of MyClass<T> as follows: MyClass<Volvo> m = new MyClass<Volvo>(); or since Java 7: MyClass<Volvo> m = new MyClass<>();

  • You really do need the Class, say because you are working with Enum types and a lot of those methods a parametrized using the relevant Class:

    public void check(Class<?extends SuperType> validClsAutomaticallyChecked) {}

  • You just need an object of a specific supertype to be passed to the method:

    public void pass(SuperType thatSimple) {}

  • You do not need, cannot or will not make your containing class take a type parameter of the thing to be passed, but you still want to leverage generics in your method. This may be useful to allow the compiler to infer that what you are doing inside the method body is safe. For example you may wish to create a collection of things of type T based on the type of thing passed as parameter to the method.

    public <T> void workWith(T genericallyTypedObject) {}

user268396
  • 11,576
  • 2
  • 31
  • 26
1

You can try also:

aClass.isAssignableFrom(v2.getClass())

Where "aClass" is a superclass of "v2"

frankfg
  • 625
  • 5
  • 13