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.
Related
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)
I'd like to store a class object in a local variable and then call its static methods. Also, the class object should expect descendant types:
class Ancestor {
static void staticMethod() {
}
}
class Descendent extends Ancestor {
}
(...)
Class<? extends Ancestor> fool = Descendent.class;
fool.staticMethod() //compilation error 'cannot resolve symbol'
How would you guys solve this?
There are multiple errors in you question, but I give you that what comes closest to an answer. First of all be aware that your using default visibility which is package. So the method can only be seen by classes in the same package.
The following snippet from you is not valid:
Class<Ancestor> fool = Descendent.class;
A valid version would be:
Class<? extends Ancestor> fool = Descendant.class;
Related to the static method invocation. You cannot invoke static methods of a class with just the class object. It is possible to invoke the method via reflection.
This could look like the following:
fool.getDeclaredMethod("staticMethod").invoke(null);
There are two special behaviors in that case.
static methods will be invoked with null as object argument
It does only work on the class object declaring the static method and not for classes extending the class with the static method.
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.
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)
I have a class named Agent:
abstract public class Agent {
// this class doesn't has the method "method_A"
}
And a class AgentHistoric:
public class AgentHistoric extends Agent{
public void method_A(){
code
}
}
I have also classes RandomAgent, AgentAlways0, etc, all extending the abstract class Agent, but only AgentHistoric has the method "method_A".
Suppose I created AgentHistoric's objetcs, RandomAgent's objetcs, etc, and I have added them to an ArrayList named agents.
In another class, I have the following code:
for (Agent ag: this.agents ){
ag.update(); // all Agent's subclasses have this method
if (ag.returntype() == AgentHistoric){ // I know there's a more elegant way, but OK
method_A() } // error!
}
How can I execute a exclusive method of AgentHistoric in this loop?
Use the instanceof operator to determine if ag is an AgentHistoric. If so, cast ag to an AgentHistoric, then call method_A.
Maybe try to use instanceof operator?
if (ag instanceof AgentHistoric){
...
}
Instead of using instanceof, a more "OO way" of doing it is just NOT override method_A in the classes that you want to run Agent.method_A() or if you want to do additional work, call super.method_A() while in the classes that you want to change the implementation - override the method.
The compiler only knows that the variable ag is of type Agent which, as you said yourself, has no method_A defined. In order to call method_A, you need to cast ag to an instance of AgentHistoric.
As others have said, you can use the instanceof operator to check that the current assignment of ag is in fact an AgentHistoric instance.