Checking if object is instance of a generic parent class - java

I have a class I am obtaining by using Class.forName like this
Class<?> processClass = Class.forName(entity.getClassname());
I need to know if processClass is an instance of this type
(Class<? extends Job>)
How can I check this in Java? I mean I need to do something like this:
if (processClass.isAssignableFrom((Class<? extends Job>))){
....
}
How can that be achieved in Java?

I assume you want to test
Job.class.isAssignableFrom(processClass)

Related

Passing Class<?> cls as a method parameter?

I'm having trouble completing this method.
I am trying to write a method that will let my main pass two parameters: a Talker object instance and cls a Class object representing the type which the Listener should extend from in order to receive the message. I'm very new to Java and could use some help with this.
Here's the code for the method:
public void sMessage(Talker talker, Class<?> cls) {
for ( Listener l : mParticipants)
{
if (cls.isAssignableFrom(cls.getSuperclass())) {
l.onMessageReceived(talker.getMessage());
}
}
}
Not sure how I should complete this, or how to make a call from main:
singletonDemo.sMessage(demoTalker, Class?);
Not really following the examples I've seen so far. Any suggestions?
#BornToCode is correct about calling the method, but what you want to achieve with the method is still slightly wrong.
cls.isAssignableFrom(cls.getSuperclass())
will always return false. This is because you cannot take a parent class and assign it to the child class. I believe what you are looking for is a way to check if the listener extends the class specified. You can do this by getting the class of the listener.
cls.isAssignableFrom(l.getClass())
or more simply
cls.isInstance(l)
I do not understand what cls should represent. However, you should get something like:
singletonDemo.sMessage(demoTalker, SomeClass.class);
or:
singletonDemo.sMessage(demoTalker, someClassInstance.getClass());
For your information, cls.isAssignableFrom(cls.getSuperclass()) will always return false. The documentation of isAssignableFrom says:
Determines if the class or interface represented by this Class object is either the same
as, or is a superclass or superinterface of, the class or interface represented by the
specified Class parameter.

Function parameter Class<Type> won't accept child of type

I have one method with a parameter Class<SearchForm> formType, and in the method I call formType.newInstance() to get an instance of the form. I need to be able to pass in child classes of SearchForm, but when I try to pass in MySearchForm.class (where MySearchForm extends SearchForm), eclipse tells me I cannot pass in Class<MySearchForm> for a parameter of type Class<SearchForm>.
How can I pass in a class extending the desired parent class and then instantiate an object of that class?
You could use an upper bound generic wildcard Class<? extends SearchForm>
You can't pass in a Class<MySearchForm>, because it's not a Class<SearchForm>, even if a MySearchForm is a SearchForm.
However, you can use a wildcard parameter in your method, defined something like this:
... yourMethod(Class<? extends SearchForm> formType)

Issues using java.lang.Class as a parameter for a method

I have the following setup of classes/interfaces.
Interface IFoobar
Class BaseClass which implements IFoobar and is abstract
Class ConcreteClassA which extends BaseClass
Class ConcreteClassB which extends BaseClass
Class ConcreteClassC which extends BaseClass
I have a method for which I need to pass instances of java.lang.Class for the above concrete classes. I am declaring it like so.
void doSomething(String id, Class<IFoobar> c)
However, when I try to compile, java complains with an error more or less like this:
doSomething(java.lang.String,java.lang.Class<IFoobar>) in javaclass cannot be applied to
(java.lang.String,java.lang.Class<ConcreteClassA>)
register("12345", ConcreteClassA.class);
^
1 error
I've only recently needed to use java.lang.Class to do things, so I am guessing I am missing something simple. I would have expected the typed class declaration to work like normal parameters in that the concrete classes are recognized as instances of the interface, but this apparently isn't the case.
I've tried various methods of casting, etc and either not had the desired results, or had code which isn't valid. So any ideas as to what I need to do would be appreciated.
Thanks in advance.
A variable of type Class<IFoobar> can only hold a reference to a Class<IFoobar> object, not a Class<ConcreteClassA> object.
Change Class<IFoobar> to Class<? extends IFoobar>.
This behaviour is not particularly sensible for Class objects. It is much more logical for collections, where it stops you doing this:
void method1(List<IFoobar> list)
{
list.add(new ConcreteClassA());
}
void method2()
{
List<ConcreteClassB> list = /* something */;
method1(list);
// oops! we put a ConcreteClassA inside a List<ConcreteClassB>
}
the only accepted value for Class<IFoobar> is IFooBar.class. If you want to accept IFooBar.class and all its subclasses, you should use Class<? extends IFooBar>
The error has nothing to do with "Class"
Simply if you use
ArrayList<Object> x = new ArrayList<String>();
You get error: incompatible types
because, though the String class is a subclass of Object, ArrayList<Object> is a different type than ArrayList<String>. That is the nature of Generics.
You can use
void doSomething(String id, Class c)

Verify instanceof when i use a static class under another one

I have a class under a class like :
public class Class0 implements Class1{
static class Class2 extends Class3 {
...
}
}
In another class I want to verify if my object is an instance of Class2, using obj instanceof Class2.
So when I print the class of my object I obtain :
class Class0$Class2
My question is, how do I use instanceof in this case? because when I try Class0.??! I dont obtain Class0.Class2
Use instanceof Class0.Class2. But make sure that the class is visible. You declared the class with the package visibility.
The name Class0$Class2 is the name of your class in the compiled code. Normally you don't refer to it.
I think that if you want to make sure an object is of specific class you need to use Object.getClass() method, not instanceof operator.
Because the operator will simply return true if an given object is an instance of a given class, and this would be true for all the parent classes and interfaces in your object's hierarchy.

Java generics question - Class<T> vs. T?

I'm using Hibernate validator and trying to create a little util class:
public class DataRecordValidator<T> {
public void validate(Class<T> clazz, T validateMe) {
ClassValidator<T> validator = new ClassValidator<T>(clazz);
InvalidValue[] errors = validator.getInvalidValues(validateMe);
[...]
}
}
Question is, why do I need to supply the Class<T> clazz parameter when executing new ClassValidator<T>(clazz)? Why can't you specify:
T as in ClassValidator<T>(T)?
validateMe.getClass() as in ClassValidator<T>(validateMe.getClass())
I get errors when I try to do both options.
Edit: I understand why #1 doesn't work. But I don't get why #2 doesn't work. I currently get this error with #2:
cannot find symbol
symbol : constructor ClassValidator(java.lang.Class<capture#279 of ? extends java.lang.Object>)
location: class org.hibernate.validator.ClassValidator<T>
Note: Hibernate API method is (here)
Because T is not a value - it's just a hint for the compiler. The JVM has no clue of the T. You can use generics only as a type for the purposes of type checking at compile time.
If the validate method is yours, then you can safely skip the Class atribute.
public void validate(T validateMe) {
ClassValidator<T> validator =
new ClassValidator<T>((Class<T>) validateMe.getClass());
...
}
But the ClassValidator constructor requires a Class argument.
Using an unsafe cast is not preferred, but in this case it is actually safe if you don't have something like this:
class A {..}
class B extends A {..}
new DataRecordValidator<A>.validate(new B());
If you think you will need to do something like that, include the Class argument in the method. Otherwise you may be getting ClassCastException at runtime, but this is easily debuggable, although it's not quite the idea behind generics.
Because ClassValidator is requiring a Class object as its parameter, NOT an instance of the class in question. Bear in mind you might be able to do what you're trying to do with this code:
ClassValidator<? extends T> validator = new ClassValidator<? extends T>(validateMe.getClass());

Categories

Resources