Essentially what I want to do is pass a class as a parameter so that I can preform an instanceof comparison.
public class MyClass
{
Object o = something;
public void myMethod(Class c)
{
if(o instanceof c)
{
do something
}
}
}
Where the parameter Class c is any class that I choose to pass in from else where. Essentially I want to be able to pass in any class and make a comparison.
Any help would be appreciated.
Thanks
You can call Class#isInstance(Object obj):
if(c.isInstance(o)) {
Determines if the specified Object is assignment-compatible with the object represented by this Class. This method is the dynamic equivalent of the Java language instanceof operator.
Just let the method accept Object. In Java all classes extend from Object.
public class MyClass
{
Object o = something;
public void myMethod(Object c)
{
if(o.isInstance(c))
{
do something
}
}
}
Related
The scenario is that I am passing an object as a parameter in a method and I want to perform operations based on the type of that object within the method.
Sample code is:
method(Object object){
//if object== String type print string
}
Use instanceof keyword. The keyword instanceOf in java programming language is a boolean operator that is used to test whether an object is of an specified type or not and returns the value accordingly.
if(object instanceof String) {
}
Try
if (object.getClass().getName().equals("Class1Name"))
//do something.
The advantage of getClass instead of instanceof is that you do not need to know the class type at compile time.
You can use the instanceof operator in java.
Please check the bellow link
Click here for an example
If you want method to react differently according to the parameter you should overload it
public void method(String s) {
}
public void method(Integer i) {
}
public void method(SomeClass o) {
}
Use instanceof operator to check the type and cast appropriately
You can use the instanceof keyword. Be forewarned, though; this is not normally a good practice unless you're absolutely unsure of what kind of Object you'll be passing through.
The good practice is using polymorphism ..
Where you have a parent class that has a property that represent which childType is this,
class Parent { string type; public string getType() { return type; } }
class ChildA extends Parent { ChildA() { type = "ChildA"; }
class ChildB extends Parent { ChildB() { type = "ChildB"; }
public void function (Parent p)
{
if (p.getType() == "ChildA")
{
// A
}
else if (p.getType == "ChildB")
{
// B
}
}
If you plan just to print something, you can use toString() method that will be override on each different type of object ;)
just use something like the code bellow and let each class have a different toString() method:
method(Object object){
// ... object.toString();
}
I think you can use getclass() method instead.
I have a set of POJOs with a common superclass. Those are stored in a two-dimensional array of type superclass. Now, I want to obtain an object from the array and use methods of the subclass. This means I have to cast them to the subclass. Is there a way to do this without using instanceof?
Update: As a concrete example: http://obviam.net/index.php/the-mvc-pattern-tutorial-building-games/ See: "Add new actions (attack) when an enemy is clicked"
Yes - you can do it by inverting the flow: instead of your code doing something when the instance of the base class is of a specific type, pass an action item to the object, and let the object decide whether to perform it or not. This is the basic trick behind the Visitor Pattern.
interface DoSomething {
void act();
}
abstract class AbstractBaseClass {
abstract void performAction(DoSomething ds);
}
class FirstSubclass extends AbstractBaseClass {
public void performAction(DoSomething ds) {
ds.act();
}
}
class SecondSubclass extends AbstractBaseClass {
public void performAction(DoSomething ds) {
// Do nothing
}
}
AbstractBaseClass array[] = new AbstractBaseClass[] {
new FirstSubclass()
, new FirstSubclass()
, new SecondSubclass()
, new FirstSubclass()
, new SecondSubclass()
};
for (AbstractBaseClass b : array) {
b.performAction(new DoSomething() {
public void act() {
System.out.println("Hello, I'm here!");
}
});
}
If you know they're of the subclass type, then just cast them directly without an instanceof check.
But putting them in a superclass-typed array is telling the compiler to discard the information that they're actually of the subclass type. Either your superclass should expose those methods (perhaps as abstract), or your array should be of the subclass type (so you're not telling the compiler to forget the actual type of the objects), or you'll have to suck it up and do the cast (possibly with the instanceof test).
The only other notable alternative is that you might experiment with the visitor pattern, which passes an action to the object and lets the object decide what to do with it. That lets you override classes to ignore or perform the actions based on their runtime type.
You can try to use the Visitor design pattern.
http://en.wikipedia.org/wiki/Visitor_pattern
You have to ask yourself, why do you need to know their type, maybe this can be replaced with the use of an abstract method in the super class, that every one of them can implement according the desired result.
abstract class A{
abstract void visit();
}
class B extends A{
void visit() { print("B"); }
}
class C extends A {
void visit() { print("C"); }
}
I would avoid casting them in the first place.
Really think about what you're trying to do, and if they should be in the same collection like that.
If you have something like this
for(MyObj o : array) {
if(o instanceof A) {
((A)o).doA();
}
if(o instanceof B) {
((B)o).doB();
}
}
consider this instead
abstract class MyObj {
abstract void doIt();
}
class A {
void doIt() { doA(); }
}
class B {
void doIt() { doB(); }
}
Expose the method in the superclass, and then use overriding. Provide an empty implementation in the base class so that subclasses can ignore the action if needed.
I have a base class called class Base and two children classes
class A extends Base
and
class B extends Base
I have a method foo in Base.
Rather than putting the implementation of foo in class A and class B, so that I can do
void foo (Object o)
{
// A's implementation
assert o instanceof A;
}
void foo (Object o)
{
// B's implementation
assert o instanceof B;
}
Is there anyway to put foo in Base, and still still be able to check for the runtime class? I've thought of something like this:
void foo (Object o)
{
// Check that o is instanceof a runtime class
assert o instanceof this.getClass(); // ????
}
Thanks.
You can implement your method like this:
public void foo() {
if (this instanceof A) {
// implementation for A
}
else if (this instanceof B) {
// implementation for B
}
}
But the point of polymorphism is to put the A implementation in A, so that this implementation can use A's private fields to implement the method (same for B, or course).
getClass().isInstance(o)
That said, perhaps you want to constrain the type in a way the compiler can check? Generics can do that:
class Base<T extends Base<B>> {
void foo(T o) { ... }
}
class A extends Base<A> {
#Override void foo(A o) { ... }
}
Then,
new B().foo(new A());
will not compile.
There is class method isAssignableFrom()
getClass().isAssignableFrom(o.getClass())
instanceof will not work since the parameter can not be 'dynamic'.
You could use the isInstance method of Class
void foo (Object o)
{
// Check that o is instanceof a runtime class
assert getClass().isInstance(o);
}
but this has at least one possible problem:
it will result in an AssertionException if this is an instance of a subclass of A and the object is just a direct instance of A!
In Java, you can check the class of an object using the instanceof operator:
object instanceof M
When you have a Class object, it would make sense to write:
object.getClass().isAssignableTo(MyClass.class)
http://www.ralfebert.de/blog/java/isassignablefrom/
public class Test {
private static Object createInstance(String classPath) {
try {
Class<?> tClass = Class.forName(classPath);
if (tClass != null) {
return tClass.newInstance();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#SuppressWarnings("unchecked")
public final static <INPUT, OUTPUT> Filter<INPUT, OUTPUT> getFilter(String path) {
return (Filter<INPUT, OUTPUT>) createInstance(path);
}
public final static <INPUT, OUTPUT> OUTPUT filter(String path, INPUT mes) {
Filter<INPUT, OUTPUT> filter = getFilter(path);
//How to check the INPUT and OUTPUT type here?
//if(INPUT instanceof String){ ... } not work
return filter.filter(mes);
}
}
refer to my earlier question here
thanks for help :)
Other answer are certainly correct. Anyway i think you are doing something quite unusual.
I'll try to explain:
Generics are use for static polymorphism. An instance of a generic type is determined at compile time.
Constructs like instanceof are used to check dynamic type of an object at runtime, so if you are using them, you can simply avoid the use of generics.
(You can use a generic Object as parameter for your function and then use instanceof to check its type)
For example:
public void method(Object o){
if (o instanceof String){} //do what you want
else ....
}
Typically, if you use generics, you are just trying to avoid that constructs. Typically a generic type can implements a well know interface, in a way that any operation performed upon that object into your filter method, could be performed for different types of objects implementing that interface and without knowing the specific type of objects involved.
I don't know exactly what are the polymorphic feature that you need, anyway you could try also something like that:
public interface polymorphicObj{
public method();
}
public class Filter<GENERIC implements polymorphicObj>{
public filter(GENERIC obj){
obj.method(); //you don't need to know of which specific type is polymorphicObj
}
}
if mes instanceof String should work.
Instead of checking INPUT, how about checking the actual parameter?
if(mes instanceof String) {
You will need instance of INPUT:
class A<INPUT>{
void typeOf(INPUT input){
if(input.getClass() == "".getClass()){
System.out.println("Input is String");
}
}
}
all objects extends Object co they have getClass method. You could use it to check class.
Is there a way to find out the name of derived class from a base class instance?
e.g.:
class A{
....
}
class B extends A{
...
}
class c extends A{
...
}
now if a method returns an object of A, can I find out if it is of type B or C?
using either instanceof or Class#getClass()
A returned = getA();
if (returned instanceof B) { .. }
else if (returned instanceof C) { .. }
getClass() would return either of: A.class, B.class, C.class
Inside the if-clause you'd need to downcast - i.e.
((B) returned).doSomethingSpecificToB();
That said, sometimes it is considered that using instanceof or getClass() is a bad practice. You should use polymorphism to try to avoid the need to check for the concrete subclass, but I can't tell you more with the information given.
Have you tried using instanceof
e.g.
Class A aDerived= something.getSomethingDerivedFromClassA();
if (aDerived instanceof B) {
} else if (aDerived instanceof C) {
}
//Use type-casting where necessary in the if-then statement.
Short answer to your question
Is there a way to find out the derived class's name from a base class object?
no, the super-class has no way of telling the name/type of a sub-class.
You have to interrogate the object (which is an instance of a sub-class) and ask if it is an: instanceof a particular sub-class, or call it's getClass() method.
You can do it in the subclass' constructor
class A {
protected String classname;
public A() { this.classname = "A"; }
public String getClassname() { return this.classname; }
}
class B extends A {
public B() {
super();
this.classname = "B";
}
}
So
A a = new A();
a.getClassname(); // returns "A"
B b = new B();
b.getClassname(); // returns "B"
((A)b).getClassname(); // Also returns "B"
Because it is casted into an "A" object, it will call the "A" getClassname() function but will return a value set by the constructor that was the "B" constructor.
Note: Call super(); before setting it
There are 2 ways I can think of
1) One with Using the Java reflection API
2) Other one would be with the instanceOf
Other method can be a Comparing objects to objects, I dont know how it might be, you can try this
Is there a way to find out the name of derived class from a base class instance?
As answered here, you can use this extremely simple approach.
abstract class A {
public final String getName() {
return this.getClass().getName();
}
}
class B extends A { }
class C extends A { }
then simply print the current class name:
B b = new B();
C c = new C();
System.out.println(b.getName());
System.out.println(c.getName());
Output:
com.test.B
com.test.C
There is no need to store additional Strings, check instanceof or override the method in any subclass.
A more modern approach (Java 16+) would be using pattern matching for the instanceof operator. The syntax is pretty simple:
if(x instanceof X xChild){
// use xChild
}
It is both shorter and less error-prone as it combines all the steps of testing the runtime type of the variable(x in the example above), casting it down, and assigning it to a new variable(`xChild in the example above). Read more.
Another example:
public void addUIControl(UIControl control) {
if(control instanceof SelectList sl){
selectList = sl;
}
else if(control instanceof TextBox tb){
textBox = tb;
}
else if(control instanceof Button btn){
button = btn;
}
else {
throw new IllegalArgumentException("Uknown UIControl object has been passed to the SendFormMediator");
}
}