I have a Class object. I want to determine if the type that the Class object represents implements a specific interface. I was wondering how this could be achieved?
I have the following code. Basically what it does is gets an array of all the classes in a specified package. I then want to go through the array and add the Class objects that implement an interface to my map. Problem is the isInstance() takes an object as a parameter. I can't instantiate an interface. So I am kind of at a loss with this. Any ideas?
Class[] classes = ClassUtils.getClasses(handlersPackage);
for(Class clazz : classes)
{
if(clazz.isInstance(/*Some object*/)) //Need something in this if statement
{
retVal.put(clazz.getSimpleName(), clazz);
}
}
You should use isAssignableFrom:
if (YourInterface.class.isAssignableFrom(clazz)) {
...
}
you can use the below function to get all the implemented interfaces
Class[] intfs = clazz.getInterfaces();
You can use class.getInterfaces() and then check to see if the interface class is in there.
Class someInterface; // the interface you want to check for
Class x; //
Class[] interfaces = x.getInterfaces();
for (Class i : interfaces) {
if (i.toString().equals(someInterface.toString()) {
// if this is true, the class implements the interface you're looking for
}
}
You can also set the instance adding ".class"
Class[] classes = ClassUtils.getClasses(handlersPackage);
for(Class clazz : classes)
{
if(Interface.class.isAssignableFrom(clazz))
{
retVal.put(clazz.getSimpleName(), clazz);
}
}
A contribution for all the other answers, when possible do not use the most updated answer of method isAssignableFrom, even the "not great" answer of using clazz.getInterfaces() has better performance than isAssignableFrom.
A common mistake for developers when looking for an answer to the OP question, is to prefer isAssignableFrom when an instance is available, wrongly doing this:
if (IMyInterface.isAssignableFrom(myObject.getClass())) {
...
When possible, use IMyInterface.class.isInstance or instanceof as both of those have way better performance. Of course, as the OP stated; they have the drawback that you must have an instance and not just the class.
if (IMyInterface.class.isInstance(myObject)) {
...
if (myObject instanceof IMyInterface) { // +0.2% slower than `isInstance` (*see benchmark)
...
An even faster, but ugly solution would be to store an static Set with all the "valid" classes instead of checking them, this ugly solution is only preferred when you need to test classes a lot, as its performance outperforms all the other approaches for direct class check.
public static final Set<Class<?>> UGLY_SET = Stream.of(MyClass1.class, MyClass2.class, MyClass3.class).collect(Collectors.toCollection(HashSet::new));
if (UGLY_SET.contains(MyClass)) {
...
(*) JMH Benchmark for +0.2%
Please visit this answer from users #JBE, #Yura and #aleksandr-dubinsky, credits for them. Also, there's plenty of detail in that answer for the benchmark results to not be valid, so please take a look into it.
Related
This is more like a "good practice" question.
let's say i have an interface "MyInterface" and about 15 implementations of it.
I have an Object called "MyProcess" and the code looks like
private final List<MyInterface> myInterfaces;
public MyProcess(#Qualifier("impl1") MyInterface impl1,
#Qualifier("impl2") MyInterface impl2,
#Qualifier("impl3") MyInterface impl3,
#Qualifier("impl4") MyInterface impl4,
#Qualifier("impl5") MyInterface impl5,
#Qualifier("impl6") MyInterface impl6,
#Qualifier("impl7") MyInterface impl7,
#Qualifier("impl8") MyInterface impl8) {
this.myInterfaces = Stream
.of(impl1,
impl2,
impl3,
impl4,
impl5,
impl6,
impl7,
impl8)
.collect(toList());
}
The goal is to define different processes using some of the implementations of MyInterface in a specific order. The issue is that sonar rule S107 (constructor has 8 parameters which is greater than 7 authorized) is showing. I was wondering if this was a code structure issue or if i just had to ignore sonar on this. I dont feel like breaking SRP since the only goal of MyProcess is to define the list of MyInterface it needs.
Does anyone have a clue on how i could improve this code ? Maybe an other pattern to use ?
Thank you in advance for your time
One alternative is to add a method name() to MyInterface, which is implemented in each subclass as returning a constant String.
public MyProcess(List<MyInterface> impls) {
this.myInterfaces = new ArrayList<MyInterface>();
for(String name: Arrays.asList("impl1", "impl2"...) {
for(MyInterface impl: impls) {
if(name.equals(impl.name())) {
myInterfaces.add(impl);
}
}
}
}
I feel that hard-coding the names of the implementation in the process might not be ideal. If you already have 15 implementations, the odds are that you might in the future have to add one. And then you would need to update the Process as well.
You let the MyInterface return something else than a name, e.g. a 'purpose' and a 'priority', so the process could wire new implementations automatically in the correct place, but that depends on your usecase.
If I want to read some JSON into an object, and I have the interface but must use the Spring context to get the implementation class, I need to use a SimpleAbstractTypeResolver to map the interface to the implementation. So far, so good, if I know in advance what interfaces go to what implementation. But if the interface has methods that return other interfaces--and possibly down the line recursively--and I don't necessarily know in advance, I thought I could use reflection to figure it out. So this is what I came up with, but the compiler does NOT like the line resolver.addMapping(method.getReturnType(), method.getReturnType());, says it's not applicable for these arguments. I'm pretty sure the types are okay for that method--any thoughts on how to make this happen?
for (Method method : clazz.getMethods()) {
if (method.getReturnType().isInterface() && method.getName().startsWith("get")) {
// getter method returns an interface so find its implementation class
Class beanClass = context.getBean(method.getReturnType()).getClass();
if (clazz.isAssignableFrom(beanClass)) {
resolver.addMapping(method.getReturnType(), method.getReturnType());
mapInterfaces(objectMapper, clazz, resolver);
}
}
}
Probably you need to review your types.
My guess is following:
resolver.addMapping(method.getReturnType(), beanClass);
(replace second parameter method.getReturnType() with beanClass)
or as an alternative (the code is not completely clear for me, sorry)
resolver.addMapping(clazz, beanClass);
You should put an Interface and Implementation into addMapping().
Example:
interface ITest{};
class TestImpl implements ITest {}
usage:
resolver.addMapping(ITest.class, TestImpl.class);
Probably you need to review your types.
My guess is following:
new ObjectMapper().writerFor(<Interface>.class).writeValuesAsArray(<Class>);
I am going through dozen tutorials which prove to me of very little help because production code is not an animal, bird or human. Not a weapon of type cutting or shooting it is much more complex to reason about.
So returning to reality, scenario:
service 1 is exchanging messages with service 2 through Kafka, messages are serialized/deserialized with Jackson, the model class is shared between services as jar.
Now the plague part, the culmination of evil :
#JsonTypeInfo(
use = Id.NAME,
property = "type",
visible = true
)
#JsonSubTypes({#Type(
value = InternalTextContent.class,
name = "text"
), #Type(
value = InternalImageContent.class,
name = "image"
), #Type(
value = InternalAudioContent.class,
name = "audio"
), #Type(
value = InternalCustomContent.class,
name = "custom"
)})
public abstract class InternalContent {
#JsonIgnore
private ContentType type;
public InternalContent() {
}
Obviously when the time will come to work with this content we will have something like:
message.getInternalContent
which results to a sea of switch statements, if conditions, instanceof and wait for it ... downcasting everywhere
And this is just one property example the wrapping object contains. Clearly I cannot add polymorphic behaviour to InternalContent , because hellooo it is within a jar.
What went wrong here? Is it even wrong?
How do I add polymorphic behaviour ? To add a new mitigating layer, I still need instanceof in some factory to create a new type of polymorphic objects family which are editable to add the desired behavior? Not even sure it is going to be better, it just smells and make me want to shoot the advocates which throw blind statement like instanceof with downcasting is a code smell" torturing people like me who genuinely care, which makes me wonder if they ever worked on a real project. I deliberately added system environment details to understand how to model not just the code but interaction between systems. What are possible redesign options to achieve the "by book" solution?
So far I can think of that sharing domain model is a sin. But then if I use different self-service-contained classes to represent same things for serialization/deserialization I gather flexibility but lose contract and increase unpredictability. Which is what technically happens with HTTP contracts.
Should I send different types of messages with different structures along the wire instead of trying to fit common parts and subtypes for uncommon in a single message type?
To throw more sand at OO , I consider Pivotal the best among the best yet:
https://github.com/spring-projects/spring-security/blob/master/core/src/main/java/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.java
public boolean supports(Class<?> authentication) {
return (UsernamePasswordAuthenticationToken.class
.isAssignableFrom(authentication));
}
AuhenticationManager has a list of AuthenticationProviders like this and selects correct one based on the method above. Does this violate polymorphism ? Sometimes it all just feels as a hype...
Use the visitor pattern.
Example (I'll limit to two subclasses, but you should get the idea):
interface InternalContentVisitor<T> {
T visitText(InternalTextContent c);
T visitImage(InternalImageContent c);
}
public abstract class InternalContent {
public abstract <T> T accept(InternalContentVisitor<T> visitor);
// ...
}
public class InternalTextContent {
#Override
public <T> T accept(InternalContentVisitor<T> visitor) {
return visitor.visitText(this);
}
}
public class InternalImageContent {
#Override
public <T> T accept(InternalContentVisitor<T> visitor) {
return visitor.visitImage(this);
}
}
This code is completely generic, and can be shared by any application using the classes.
So now, if you want to polymorphically do something in project1 with an InternalContent, all you need to do is to create a visitor. This visitor is out of the InternalContent classes, and can thus contain code that is specific to project1. Suppose for example that project1 has a class Copier that can be used to create a Copy of a text or of an image, you can use
InternalContent content = ...; // you don't know the actual type
Copier copier = new Copier();
Copy copy = content.accept(new InternalContentVisitor<Copy>() {
#Override
public Copy visitText(InternalTextContent c) {
return copier.copyText(c.getText());
}
#Override
public Copy visitImage(InternalImageContent c) {
return copier.copyImage(c.getImage());
}
});
So, as you can see, there is no need for a switch case. Everything is still done in a polymorphic way, even though the InternalContent class and its subclasses have no dependency at all on the Copier class that only exists in project1.
And if a new InternalSoundContent class appears, all you have to do is to add a visitSound() method in the visitor interface, and implement it in all the implementations of this interface.
I am creating a class that overrides a method signature whose erasure is identical between 2 implemented interfaces, but with a minor difference in regards of the generic type (one is a method-inferred type, the other an inferred-class type). I am looking for a neat solution. I CAN ONLY edit the inherited class, not the original legacy interfaces.
To show the case, I made up an abstract sample, to understand the problem:
I got a Developer legacy parent class:
public class Developer<C>{
Rate<C> getRate(Taxes<C> tax){ /*...*/ }
}
I also got a Rentable legacy interface, with an almost identical signature
public interface Rentable {
<C> Rate<C> getRate(Taxes<C> taxes);
}
As a developer is not rentable, in my model, I create an special
developer which is both a Developer, and Rentable material.
public class OutsourcableDeveloper<C>
extends Developer<C>
implements Rentable{
#Override
public Rate<C> getRate(Taxes<C> taxes){ /*...*/}
}
and then I got the infamous
Name clash: The method getRate(Developer.Taxes) of type
OutsourcableDeveloper has the same erasure as
getRate(Developer.Taxes) of type Rentable but does not override it
How can I get rid of it, so OutsourcableDeveloper.getRate() hides
both Developer and Rentable. getRate()?
It seems a bit illogical to fail a common override but then disallowing extending both signatures as the erasures are equal.
Does it really matters so much the fact that one of the supertypes infers type from de method and the other from the class specially when I'm not going to call any super in my implementation? Is there perhaps a trick to overcome the issue given this simplification?
EDIT: I opened a more abstract, less solution-oriented to my actual problem, question to discuss the inheritance design problem which I believe is the correlated essence of the actual issue I am having: Why can't I extend an interface "generic method" and narrow its type to my inherited interface "class generic"?
EDIT2: Previous question lead me to the answer posted here
Well they are actually not equal. Because any Rentable-Instance allows any typeparameter T to be given, while the OutsourcableDeveloper restricts it.
Of course you can assume that in your case it is easy to use the
<C> Rate<C> getRate(Taxes<C> taxes);
Version of the interface. But expect how confused a developer could be, if he wants to subclass OutsourceableDeveloper. From the definition of Developer he can assume that the Method getRate is fixed to C but actually it can suddenly take any value. -> allowing this would lead to confusion.
What i can offer you is the following code-example, which may be suitable for your case. Although it definitely will be inconvenient to use it. But as you forward all methods to the OursourcableDeveloperRentable it is possible. The comments should explain how it works.
//This class itself can be added to any Developer-lists
public class OutsourcableDeveloper<C> extends Developer<C> {
public final OutSourcableDeveloperRentable RENTABLE_INSTANCE = new OutSourcableDeveloperRentable();
#Override
public Rate<C> getRate(final Taxes<C> taxes) {
// Simply forward to the more general getRate instance.
return this.RENTABLE_INSTANCE.getRate(taxes);
}
public void exampleBehaviourA() {
//Example for how you can make both objects behave equally.
}
// This class can be added to the lists requiring a Rentable
// And the original value can be retrieved by both classes.
public class OutSourcableDeveloperRentable implements Rentable {
public final OutsourcableDeveloper<C> PARENT_INSTANCE = OutsourcableDeveloper.this;
//This method is the one to implement because it is more general than
//the version of OutsourcableDeveloper.
#Override
public <T> Rate<T> getRate(final Taxes<T> taxes) {
// Do your work.
return null;
}
public void exampleBehaviourA() {
//Just an example - Maybe for you it makes for sence to
//forward the method of Oursoursable-Developer to here.
//Then all Behaviour would be found in this class.
OutsourcableDeveloper.this.exampleBehaviourA();
}
}
}
Ok, I found a way to solve it. It's clumpsy, but it's the easier one if the architecture is not very complex, inspired by my Why can't I extend an interface "generic method" and narrow its type to my inherited interface "class generic"? own answer:
public class OutsourcableDeveloper<C>
extends Developer<C>
implements Rentable{
/* This might not be needed if we don't need to extract C from taxes parameter */
final Class<C> currencyClass;
public OutsourcableDeveloper(Class<C> currencyClass){ this.currencyClass = currencyClass;}
#Override
public Rate<C> getRate(#SuppressWarnings("rawtypes") Taxes taxes){
try{
C taxesCurrency = (C) currencyClass.cast(taxes.getCurrency()); //IF actually needed getting the typed instance
return new Rate<C>(taxesCurrency); //Or whatever processing
} catch (ClassCastException e){
throw new UnsupportedOperationException("OutsourcableDeveloper does not accept taxes in a currency that its not hims");
}
}
}
It is also possible to play with "extends Developer" without the generic type, so it is implictly raw. but we loose typing for the non-conflicting methods as well
Say I have this class :
public class BaseJob{
String name;
public void setName(String name){
this.name=name;
}
public String getName()
{
return name;
}
}
and another class that extends it :
public class DetailedJob extends BaseJob{
public void doThing();
}
Furthermore, I have this method in another class :
List<BaseJob> getSomeJobs()
Now, my problem is :
is it possible to avoid to cast each item sequentially in the returned list of getSomeJobs, if I know for sure that every BaseJob returned is indeed a DetailedJob ?
Put differently, is there another solution than the following to cast all items in the list :
List<BaseJob> baseJobList = getSomeJobs();
List<DetailedJob> detailedJobList = new ArrayList<DetailedJob>();
for (BaseJob baseJob : baseJobList)
detailedJobList.add((DetailedJob) baseJob);
Probably what you want to do is parameterising the class that defines getSomeJobs.
public final class JobHolder<T extends BaseJob> {
public List<T> getSomeJobs() {
...
Generally unchecked casts indicate a design problem. They are unavoidable in certain situations such as low-level implementations and when dealing with serialisation.
If you know that all of the jobs are going to be detailed jobs, why would you put them in an arraylist of basejobs? There's no reason to, and that method would eliminate many possible errors and exceptions.
Well, there's:
List<BaseJob> baseJobList = getSomeJobs();
#SuppressWarnings("unchecked")
List<DetailedJob> detailedJobList = (List) baseJobList;
The downside of this is that if any of the jobs in the list aren't detailed jobs, the exception will only be thrown when someone tries to fetch it. Also, if a new non-detailed job is added to baseJobList afterwards, that could screw up anyone using detailedJobList. Basically you've lost a lot of type safety. In some cases you may not care, but it's not something you should do lightly.
You could create a parameterized getSomeJobs method to take in an argument saying that you know everything is a DetailedJob, meaning that it would return a DetailedJob list rather than the base class.
If you use instanceof, you wouldn't even need to cast, you could just ask if each element is an instance of a DetailedJob and proceed for there. This is almost no better than looping through each object and casting, however.
While it doesn't directly solve your casting problem I'd be temped to use two methods on the 'other class':
List<BaseJob> getAllJobs();
and
List<DetailedJob> getDetailedJobs();
This makes your code more readable to anyone using the 'other class' and will hopefully prevent mistakes.
Either that or I'd genericise the 'other class' like #Tom Hawtin suggests.
Your other class that provides the getSomeJobs method should implement an interface (to help with your unit testing, among other things). Let's call it JobProvider. You can declare the interface such that it will always produce a list of something that extends a base job, and in subclasses where you know your job is always going to be of a certain sub-type, you can narrow the type definition there.
interface JobProvider {
List<? extends BaseJob> getSomeJobs();
}
class JobProviderImpl implements JobProvider {
public List<DetailedJob> getSomeJobs() {
// do stuff and return
}
}
Now, in other code, if you know you're dealing with a JobProviderImpl, you can case it and know that the list will contain only DetailedJobs.
if (provider instanceof JobProviderImpl) {
List<DetailedJob> detailedJobs = ((JobProviderImpl) provider).getSomeJobs();
}
Make getSomeJobs() or write another function getSomeDetailedJobs() that returns
List < DetailedJob> instead of List < BaseJob>. I dont know how else we can be "sure" about all elements being of type DetailedJobs.