start() and poll() are abstract so in my class which extends from SourceTask I can do the following:
public void start(Map<String, String> props, Object anotherParameter)
{
//whatever
}
public List<SourceRecord> poll(Object anotherParameter) throws InterruptedException
{
//whatever
}
But how does the code invoking 'poll(whateverObject)' or 'start(props, whateverObject)' do initialize the whateverObject and reference it properly when invokating it? Because I can not customize the code which invokes this methods, right? Or can I? And if yes, how?
I have seen other Connectors implementations where this is done but I do not understand how it can work.
start() and poll() are abstract so in my class which extends from SourceTask I can do the following
No, you cannot "do the following" (add parameters) because those are not the method contracts.
You still need to override the actual methods, but then you could call other methods (of the same name, with parameters), if you needed to, but those wouldn't be abstract, and have no semantic meaning to be overloaded, so they could be named anything, therefore is just regular Java method calling.
I can not customize the code which invokes this methods, right?
You cannot*.
* Unless you want to rebuild Kafka Connect from source
The problem is I don't have the control of how and when poll() is invoked
That is correct. Not really clear what parameters you are trying to add, but poll certainly doesn't need anything and any object initialization you need to do should be done via the configuration (the property map passed to the start method)
Related
Below I am trying to explain the problem with an example.
We have a Caller.java
Caller.java : which calls the series of Actors to perform certain steps in sequence.
Actor.java : Abstract class containing action() method
ActorOne.java : Implements the action() method
ActorTwo.java : Implements the action() method
ActorThree.java : Implements the action() method
At runtime, based on a task to accomplish, a collection of classes is prepared inside Caller.java and instantiated using the Reflection.
Actor.java: callActions(){
Class[] classes = [ActorOne.class, ActorTwo.class]
for(Class clazz : classes){
Actor actor = (Actor) clazz.newInstance();
actor.action();
}
}
In certain situation, which I know runtime inside the callActions.java, I need to inform the ActorTwo to peform the action method differently.
My solution is to pass that flag to the ActorTwo object using Reflection API and inside the action() method put if/else to perform the flag specific action.
Is there a better way to design the solution, so that I can avoid the if/else within the ActorTwo.action() method?
Best Regards
Another option is to make the action() method take an array of arguments (like main(...) does). That way ActorTwo could check the arguments to see if its in the special case, whereas the other Actors could just ignore the input.
public abstract class Actor{
public abstract void action(String[] args);
}
public class Actor2 extends Actor{
public void action(String[] args){
if(args != null && args.length > 0 && args[0].equals("SPECIAL_CASE"){
//Do special case things
} else {
//Do regular case things
}
}
}
This formation gives you the most flexibility going forward with adding extra cases to any actors.
You could have two methods on your interface. ActorOne and ActorThree would delegate the implementation of one method to the other (maybe an abstract super class would do that). ActorTwo would do something different.
You could have another interface with the different method, and have ActorTwo implement it, and at runtime check if your object supports it
if(inSpecialCase && actor instanceof Actor2) {
((Actor2)actor).specialMethod()
Eclipse works like the second suggestion a lot, to preserve extensibility and compatibility (new interfaces are created over time and the behavior adapts depending on what level the code supports).
Use polymorphism. Define one more method in your ActorTwo.java called action(flag), and then implement the new behavior in this method. When you do not want to pass flag, normal action() should be called. When you want to pass flag, on runtime, you should call action(flag).
A word of advise, try to avoid reflection if possible. It slows down the execution. If it is not possible for your code to avoid reflection, that is fine.
I know that multiple questions have been asked about this, but none of them suit my needs. So sorry about that.
Anyways, my class AdvancedSocket extends java.net.Socket. In my class AdvancedServerServer extends java.net.ServerSocket. So, in AdvancedServerSocket, I override the accept() method to return an AdvancedSocket. Here is that method:
#Override
public AdvancedSocket accept() throws IOException {
return (AdvancedSocket) super.accept();
}
But this throws a java.lang.ClassCastException.
When you call super.accept() the code in SocketServer's accept() method is executed. That class knows nothing about the AdvancedSocket class you have defined, so whatever it returns, it won't be an instance of AdvancedSocket.
If you want to return an AdvancedSocket, you could take the Socket instance returned by the call to super.accept() and make an AdvancedSocket out of it.
I hope that helps.
in fact your accept method still returns usual socket (because you return super.accept()), how do you think it can be casted? You need convert it manually (build advanced socket on top of usual socket)
AdvancedServerSocket is not a type of AdvancedSocket, therefore it can't be done.
There must be somewhere in between where it seems logical to treat them the same, so you should be able to create an interface which defines this functionality and have both classes implement it. Then you'll be able to handle them in the same generic manner.
Are there any reason to call method from super class?
I have met lots of places where super method called instead of this method, e.g.:
public String getCustomValue() {
String value = (String) super.getValue(someArgHere);
return value;
}
Any benefits? I just see one major problem with inheritance: if I override getValue in this class or in one of its descendants getCustomValue will neglect that override and call super method.
super.getValue(someArgHere) calls the getValue method of the super class. In contrast, this.getValue(someArgHere) calls the getValue method of the current class, if defined. If the current class does not override getValue, the super class method is called.
Unless you overwrote the method getValue(...) and you are really sure (your sureness deserves a comment in the code) you want to bypass it you should not use super like you are doing. Later on if you or someone else decide to overwrite getValue(...) they probably wanted the effect to apply to getCustomValue() as well.
Although you definitely can call super.myMethodOne() from myMethodTwo(), the usual scenario is when you want to call super.myMethodOne() from myMethodOne() when you override it. Some languages like Ruby even pass up the method arguments automatically for you so that you don't have to retype them.
Here is one example:
public class A {
public void close() {
// do a bunch of things...
}
}
public class B extends A {
#Override
public void close() {
// close things related to the subclass B
// and then make sure A is closed as usual...
super.close();
}
}
There are no technical advantages of using super over this in the case where the method is not overridden.
However, one might say that it's clearer to use super instead of this for the reason you've just mentioned. If you override the function in your subclass, then you will need to use super; if you don't you can use this. Instead of playing guessing games (or forcing people to check whether the method has been overridden), you can just always use super when you mean super.
I just see one major problem with inheritance: if I override getValue in this class or in one of its descendants getCustomValue will neglect that override and call super method.
Then don't call the super method explicitly, just call getValue. If the method has not been overriden it will default to the super-method. If it has, it will use the overriden method.
I don't know if it's appropriate to ask about "benefits" in this case - it really just depends on what exactly you are trying to accomplish.
The thing is the design. When we code, we do it as per what it is!
So even if getValue is extended, its perfect, because that is what your class is suppose to do.
Normally, super is used, to obtain any information or data or side effect from the super type and modify or improve it as per your current class functionality
The only benefit is if your class overrides the method of the superclass you still can call the method of the superclass using super.
When I make my own Android custom class, I extend its native class. Then when I want to override the base method, I always call super() method, just like I always do in onCreate, onStop, etc.
And I thought this is it, as from the very beginning Android team advised us to always call super on every method override.
But, in many books I can see that developers, more experienced than myself, often omit calling super and I really doubt they do it as a lack of knowledge. For example, look at this basic SAX parser class where super is omitted in startElement, characters and endElement:
public class SAXParser extends DefaultHandler{
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase("XXY")) {
//do something
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
//do something
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equalsIgnoreCase("XXY")) {
//do something
}else () {
//do something
}
}
}
If you try to create any override method via Eclipse or any other IDE, super will always be created as a part of automated process.
This was just a simple example. Books are full of similar code.
How do they know when you must call super and when you can omit it calling?
PS. Do not bind to this specific example. It was just an example randomly picked from many examples.
(This may sound like a beginner question, but I am really confused.)
By calling the super method, you're not overriding the behavior of the method, you're extending it.
A call to super will perform any logic the class you're extending has defined for that method. Take into account that it might be important the moment when you call super's implementation in your method overriding. For instance:
public class A {
public void save() {
// Perform save logic
}
}
public class B extends A {
private Object b;
#Override
public void save() {
super.save(); // Performs the save logic for A
save(b); // Perform additional save logic
}
}
A call to B.save() will perform the save() logic for both A and B, in this particular order. If you weren't calling super.save() inside B.save(), A.save() wouldn't be called. And if you called super.save() after save(b), A.save() would be effectively performed afterwards B.save().
If you want to override super's behavior (that is, fully ignore its implementation and provide it all yourself), you shouldn't be calling super.
In the SAXParser example you provide, the implementations of DefaultHandler for those methods are just empty, so that subclasses can override them and provide a behavior for those methods. In the javadoc for this method this is also pointed out.
public void startElement (String uri, String localName,
String qName, Attributes attributes) throws SAXException {
// no op
}
About the super() default call in code generated by IDEs, as #barsju pointed out in his comment, in each constructor there's an implicit call to super() (even if you don't write it in your code), which means, in that context, a call to super's default constructor. The IDE just writes it down for you, but it would also get called if you removed it. Also notice that when implementing constructors, super() or any of its variants with arguments (i.e. super(x,y,z)) can only be called at the very beginning of the method.
How do they know when you must call super and when you can omit it calling?
Usually, if a special API method has a critical meaning to the underlying framework context life cycle, it will always be explicitly stated and highlighted in the API documentation, like the Activity.onCreate() API documentation. Moreover, if the API follows a robust design, it should throw some exceptions to alert the consumer developer at project compile time, and make sure it will not generate a fault at run time.
If this is not explicitly stated in the API documentation, then it is quite safe for the consumer developer to assume the API method is not mandatory to call when overriding it. It is up to the consumer developer to decide whether to use the default behavior (call the super method) or completely override it.
If the condition is permitted (I love open-source software), the consumer developer can always check out the API source code and see how the method is actually written under the hood. Check out Activity.onCreate() source and DefaultHandler.startElement() source for example.
The test you should do in your head is:
"Do I want all of the functionality of this method done for me, and then do something afterwards?" If yes, then you want to call super(), and then finish your method. This will be true for "important" methods such as onDraw(), which handles lots of things in the background.
If you only want some of the functionality (as with most methods that you will override) then you probably don't want to call super().
Well Xavi gave a better answer.. but you probably might be knowing what does super() do when called in a overridden method... it ads what have you done with the default behaviour..
e.g:
onDraw()
method in view class when overridden.. you draw something before saying super.onDraw() it appears once the view is fully drawn.. so here calling super is necessary since android has some critically important things to do (like onCreate())
but at the same time
onLongClick()
when you override this you don't want to call super because it brings up a dialog with list of options for a EditText or any other similar view.. Thats the basic diff.. you have choice to leave it some times.. but for other methods like onCreate() , onStop() you should let the OS handle it..
I implemented a constraint array list like
public class ConstraintArrayList<T> extends ArrayList<T> {
ConstraintArrayList(Constraint<T> cons) {this.cons = cons;}
#Override
public boolean add(T element) {
if (cons.accept(element))
return super.add(element);
return false;
}
}
If you look at the code, it simply does some pre-checking before actually letting the super class perform the actual addition of element to the list.
This tells one of the two fold reasons for method overriding:
Extensibility where you want to extend what the super class can do
Specificity where you want to add specific behaviour through polymorphism such as in the common Animal kingdom example of move semantics where the way birds move (fly) and frogs move (hop) are specific to each sub class.
I didn't get your question clearly, but if you are asking about why not calling the super method:
There is a reason for calling the super method: if there is no zero argument constructor in the parent class then it is not possible to make a child class for that, so either you need to keep a no argument constructor in the parent class or you need to define super() calling statement with argument(how much argument constructor you have used in super class) at the top of the child class constructor.
I hope this helps. If not, let me know.
For those who also wondered which overridden methods from Android Framework should call super and found this question - here's a current hint from 2019 - Android Studio 3+ will tell you when you need it.
I've been attempting to resolve my problem for about a day now, but can't seem to get anywhere. The problem:
I have a java class, ExternalClass which has 30 methods in it.
I also have an interface ExternalClassFacade.
public class ExternalClass {
public method1() {...}
public method2() {...}
...
...
public metod30(...) {...}
}
This class is an external library and I cannot modify it's code.
The class works well but I have a situation where I need to group up multiple calls on an undefined timespan to all 30 methods, delay the execution, and execute all at once (serial or parallel I don't care) at some moment.
For example, over 10 minutes, methods 1 to 30 will be called randomly 500 times, I want them to do nothing at the moment of being invoked, but after 10 minutes I want to invoke all 500 calls as they were originally called.
most of the methods require parameters which I need to remember for the moment in which i will call the methods.
I'm looking for a way to extend/wrap/composite this class, so that when someone calls any of these methods, or, a special method that will bridge the calls to the original methods so that they will be delayed till the right moment comes.
I was thinking about extending the class and overriding all methods, and managing 30 Struct-Like classes to hold the info about the calls, but that would require :
30 overrides
30 lists
30 classes
Lots of code, not very smart.
I'm looking for a better way to do this, I was thinking about catching the calls and keeping the pointer to the original method call, but this is java, so it's not possible.
Very interesting problem indeed. First question: does ExternalClass implement some interface? If it does, it simplifies stuff a lot, however if it doesn't, you can create one:
interface ExternalClassFacade {
method1();
method2();
//...
method30();
}
Don't worry, you don't have to implement it! Just copy all the method signatures from the ExternalClass. Do you know java.lang.Proxy? Wonderful tool in such problems like yours:
ExternalClass ext = //obtain target ExternalClass somehow
ExternalClassFacade extFacade = (ExternalClassFacade) Proxy.newProxyInstance(
ExternalClass.class.getClassLoader(),
new Class<?>[]{ExternalClassFacade.class},
new BatchInvocationHandler(ext));
extFacade.method1();
As you can see this magic and obscure code created something that implements ExternalClassFacade and allows you to run the same methods as ExternalClass. Here is the missing puzzle:
public class BatchInvocationHandler implements InvocationHandler {
private final ExternalClass ext;
public BatchInvocationHandler(ExternalClass ext) {
this.ext = ext;
}
#Override
public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
return MethodUtils.invokeMethod(ext, method.getName(), args);
}
}
This code itself is not doing anything useful - when you call a method on the ExternalClassFacade it forwards the call to the same named method on ExternalClass with the same arguments. So we haven't achieved anything yet. BTW I am using MethodUtils from Apache Commons Lang to simplify the reflection code a bit. Chances are you already have this library on the CLASSPATH, if not, it is just few lines of extra code.
Now look at this improved version:
private static class BatchInvocationHandler implements InvocationHandler {
private final ExternalClass ext;
private Queue<Callable<Object>> delayedInvocations = new ConcurrentLinkedQueue<Callable<Object>>();
public BatchInvocationHandler(ExternalClass ext) {
this.ext = ext;
}
#Override
public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
delayedInvocations.add(new Callable<Object>() {
#Override
public Object call() throws Exception {
return MethodUtils.invokeMethod(ext, method.getName(), args);
}
});
return null;
}
}
Now we are getting somewhere: instead of calling the method we are wrapping the call inside Callable and adding it to a delayedInvocations queue. Of course since we are no longer calling the actual method, the return value is just a placeholder. If ExternalClass methods have return types different than void, you must be very careful.
I think you see the light now. Everything you need is to create a thread that will take all the Callables collected in the queue and run them in batch. You can do it in various ways, but the basic building blocks are there. Also you might choose data structure like map or set rather than a queue. I can for instance imagine grouping methods by name for some reason.
Of course if you can use AspectJ/Spring AOP you will avoid the whole proxy infrastructure code. But the basic idea will be the same only that the API will be more pleasent.
Using AspectJ, you could introduce an interface to the class, then code to the interface. After that, you're free to add whatever behavior behind the interface that you want. Alternately, just use AspectJ to weave in the collecting/executing behavior you're looking for.
Cglib or Javassist would also let you do it more cleanly by letting you basically proxy the class by dynamic subclassing (assuming it's not final).
There are plenty of options. Those are three third-party ones that occurred to me. An advantage of some of these approaches is that they'll give you some representation of a method invocation in object form, which you can easily collect and run at a later time.
You could use an aspect to intercept all calls to execute external lib methods and to pause the Thread, writing the Thread's ID to a synchronized Set. That Set is in a singleton being watched by another Thread.
When your business rule to execute is fired, have the singleton watcher iterate the Set and notify each thread to continue processing. The aspect will continue on and execute each originally requested external method.