I have an Object named handler and an instance of Class named protocolInterface. I want to know if handler implements protocolInterface. So far as I can tell, this isn't possible without resorting to reflection.
if (handler instanceof protoInterface.getClass())
results in a flurry of parsing errors, ')' expected illegal start of expression, etc etc. So I thought I'd try the isInstance() method, but since handler is of type Object, it call's Object's IsInstance(), which has no knowledge outside of itself. So even when handler implements protocolInteface, it returns false.
How can I reconcile this? The two ways of handling this seem mutually exclusive.
There is an isInstance() method on Class that will tell you if a given object is an instance of the target type, e.g.:
if (protoInterface.getClass().isInstance(handler)) { ... }
Class handlerClass = handler.getClass();
Class protocolClass = protocolInterface.getClass();
if (protocolClass.isAssignableFrom(handlerClass)) {
... // yadda yadda yadda
}
Obviously you can make this a one-liner; I thought this made it a bit clearer.
Try this:
if(protoInterface.getClass().isAssignableFrom(handler.getClass())
Related
Consider the following two lines of code:
final List<Path> paths = new ArrayList<>();
final FileVisitor<Path> fv = new SimpleFileVisitor<>();
To me, they look quite similar. However, the second line is refused by the Java compiler (1.8) with the message "Cannot infer type arguments for SimpleFileVisitor<>".
Can anyone please explain, what's the problem?
I don't see how you may get the error message Cannot infer type arguments because your syntax is correct, except for the fact that as many have said already, the class java.nio.file.SimpleFileVisitor has only one constructor which is protected:
protected SimpleFileVisitor() {
}
This means that only children of this class can initialize an instance of SimpleFileVisitor, and that's why your code doesn't compile.
I don't know this class, but by a quick look at the code I guess they simply expect you to extend it first (or use an already existing extension coming from somewhere else), and then use it the implementations of the FileVisitor interface.
If you don't have a concrete child class to use and want to create your own MySimpleFileVisitor:
public class MySimpleFileVisitor<T> extends SimpleFileVisitor<T> {
public MySimpleFileVisitor() {
super(); //<-- here you have the right to call the protected constructor of SimpleFileVisitor
}
}
... you will then be able to instantiate your class and use the already implemented methods like this:
FileVisitor<Path> fv = new MySimpleFileVisitor<>(); //<-- here you will be able to correctly infer parameter type as you do in your List example
fv.visitFile(file, attrs); //<-- here you enter the method implemented inside SimpleFileVisitor
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 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.
I want to call some methods like isEnabled(), getAddressFromObjectPath(), etc. of BluetoothService class, but this class is mark with #hide.
I know I have two possible ways to do what I want, one is remove the #hide, and the other is using reflection. I choose to use second one.
From the example of source code, I found that
Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
IBinder b = (IBinder) method.invoke(null, "bluetooth");
if (b == null) {
throw new RuntimeException("Bluetooth service not available");
}
IBluetooth mBluetoothService = IBluetooth.Stub.asInterface(b);
However, what it gets is the IBluetooth not BluetoothService although BluetoothService extends IBluetooth.Stub indeed.
So my questions are as follows:
(1) Could I get the BluetoothService class by reflection just like previous example code ?
(2) If my first question is negative, I call getAddressFromObjectPath() directly by reflection method like following
Method method = Class.forName("android.server.BluetoothService").getMethod("getAddressFromObjectPath", String.class);
String b = (String) method.invoke(???, PATH);
what the object dose I need to fill in the invoke() method, BluetoothService ???
Any suggestion would be greatly appreciated !!!
After surveying on the internet, I got the answer. If I want to invoke a non-static method, I need to get the class and constructor first. Use the constructor to construct the instance and then I could invoke the non-static method by this instance.
However, I could not do that on BluetoothService class because if I do the constructor again, it would cause a lot of problem !
I decide to modify the IBluetooth.aidl to add the methods I need because BluetoothService extends IBluetooth. If I could get the IBluetooth instance, I could call the methods I need. Maybe, this is not a good solution but I think it would work.
Thanks a lot.
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.