Reputation: 113
I have a number of classes that my object might be at run time. Currently to check which class it is i have a number of if statements like
int id = 0;
if (object instanceof Comment) {
id = ((Comment) object).getId();
}
if (object instanceof Follow) {
id = ((Follow) object).getId();
}
if (object instanceof Like) {
id = ((Like) object).getId();
}
if (object instanceof Post) {
id = ((Post) object).getId();
}
if (object instanceof User) {
id = ((User) object).getId();
}
This works but doesn't feel very clean. I had a look at Check if an object is an instance of any one of a list of classes (Android) which suggests a way to check if the object is an instance of a class from a list of classes like
if(myClasses.contains(obj.getClass())) {
// obj is one of the classes I care about, so do something
}
However this doesn't then work as i need to go on and cast the object to that class.
Does anyone know of a cleaner way to bot check my object type is of a class from a list of classes AND then cast the object to that class.
Something like
if(myClasses.contains(object.getClass())) {
((CLASS_THAT_MATCHED) object).getId()
}
NOTE of course normally I would just make all of the Classes be subclasses of a super class that had the getID method and other methods I need. However in this specific instance these classes all need to be subclasses of a libraries class. Making them inherit from one base classes breaks code in the library. Which i know is a bad design issue on the libraries side but isn't something i can fix.
Upvotes: 2
Views: 1346
Reputation: 12949
However in this specific instance these classes all need to be subclasses of a libraries class
Then you should use an interface
:
public interface HasId{
int /* or whatever type is the ID*/ getId();
}
public class Like extends LibrarySuperClass implements HasId{
...
}
However, if Like
, Post
etc are also library classes, you can do something like this:
// UNTESTED
Object obj =...;
List list = List.of(
Like.class,
Follow.class,
Comment.class,
User.class,
Post.class,
);
Integer id = list
.stream()
.filter(class -> class.isInstance(obj))
.map(class -> (Integer) class.cast(obj).getId())
.findFirst()
.orElse(null);
Upvotes: 4
Reputation: 66
You need to use polymorphism. For example, create an interface
public interface Message {
int getId();
}
And let your classes implement it. Then you can call the getId method on each of them. Additionally, you can create an abstract class with basic functionality for the Post, Like, etc. classes. Something like that.
Upvotes: 2
Reputation: 99
Re @Alberto Sinigaglia solution,
it works excellent... but looks ridiculous after all necessary casts ;), ex:
...
Object obj = new Comment();
List<?> list = new ArrayList<>() {
private static final long serialVersionUID = 4804401786243829831L;
{
add(Comment.class);
add(Message.class);
add(Post.class);
}
};
Integer id = (Integer) list.stream().filter(c -> ((Class<?>) c).isInstance(obj))
.map(c -> (Integer) ((I_ObjectType) ((Class<?>) c).cast(obj)).getObjectId()).findFirst().orElse(null);
System.out.println("result?=" + id);
...
each Class implements:
public interface I_ObjectType {
int getObjectId();
}
Upvotes: 0