What is the Java equivalent of a JavaScript callback? [duplicate] - java

This question already has answers here:
Java Pass Method as Parameter
(17 answers)
Closed 9 years ago.
I am experienced in JavaScript but new to Java. I am trying to figure out how to pass a function as a parameter of another function. In JavaScript this would like the block in Figure 1.
Figure 1
function fetchData(url, callback) {
// Do ajax request and fetch data from possibly slow server
// When the request is done, call the callback function
callback(ajaxResponse);
}
Is there a similar way of doing this in Java? I have searched the internets, but found little that is helpful on a novice level.

Unfortunately, the only equivalent (that I know if) is defining an interface which your fetchData method will accept as a parameter, and instantiate an anonymous inner class using that interface. Or, the class calling the fetchData method can implement that interface itself and pass its own reference using this to method.
This is your method which accepts a "callback":
public void fetchData(String url, AjaxCompleteHandler callback){
// do stuff...
callback.handleAction(someData);
}
The definition of AjaxCompleteHandler
public interface AjaxCompleteHandler{
public void handleAction(String someData);
}
Anonymous inner class:
fetchData(targetUrl, new AjaxCompleteHandler(){
public void handleAction(String someData){
// do something with data
}
});
Or, if your class implements MyCoolInterface, you can simply call it like so:
fetchData(targetUrl, this);

Related

Calling a lambda function later with different objects/arguments

I am a newbie in java functional interfaces so I want to see if this is possible and if not please explain me why not and what is possible in order to achieve my idea
I have these classes
public class A {
...
public String getInfo();
...
}
public class B {
...
public String getOtherInfo();
...
}
I want to pass the references to these functions to another object like this:
obj.init(A::getInfo)
obj.init(B::getOtherInfo)
so that later I can use/call these functions on different objects of type A or B inside the build functions:
obj.build(a1);
obj.build(a2);
...
obj.build(b1);
obj.build(b2);
PS1 I cannot use regular interfaces for this cause there are lot of getters and lots of classes similar to A which I want to use for this procedure and they are not related with one another
PS2 I try to avoid reflection cause you cannot trace the function calls
PS3 my example is not exactly working as is it throws this error: "non static method cannot be referenced from a static context"
A::get is a Java Method Reference. You should be able to store it for use later. As it's an instance method you'll need the instance object as well. So something like this might work:
Function<A,String> getFunction = A::get;
And whenever you need to use it you can do
//assuming you have an object instance of A which is a
getFunction.apply(a)
You can also pass it to other methods by declaring the method to take a functional parameter like this:
public void someOtherMethod(Function<A,String> param) {
//do whatever with param.
//invoke this with an instance of A when you're ready
param.apply(a);
}
Here's a reference that might help: https://www.baeldung.com/java-8-double-colon-operator
Made 2 mistakes
should have used Function<T, R> instead of Supplier
the error is thrown even if there is a slight mismatch of parameters even on the generic types. So an example of my function which accepts the Function parameter should be declared like this:
public <T extends Base> init (Function <T, String> f){
this.f = f;
}
and later I do something like:
public String build (A a){
return this.f.apply(a);
}
(so I had to make A, B implement some useless interface)

How to get the "host" object java [duplicate]

This question already has answers here:
How to access an object's parent object in Java?
(4 answers)
Closed 3 years ago.
I need to get the "host" object of another object. Here an example
Suppose I have the
class Peer {
final Service service;
public Peer(Service service) {
this.service = service;
}
public void ping() {
service.ping();
}
}
and
class Service {
public String hola() {
this.getPeer()? //HERE I NEED SOME COMMAND TO GET the Peer object, is this possible?
}
}
Then in Service class, I need to get the peer object. Is this possible?
You need to store the Peer object inside your Service object while creating an instance of Service, that's the only way for retrieving it.
Create inside Service a constructor which accepts Peer
class Service {
Peer peer;
public Service(Peer peer){
this.peer = peer;
}
public Peer getPeer() {
return peer;
}
public String hola() {
Peer peer = getPeer();
}
}
Thing is:
this.getPeer()? //HERE I NEED SOME COMMAND TO GET the Peer object, is this possible?
There is no "command" to do that. Simply spoken: java objects have no notion of the context they were created in. The only way for an instance of Service to know about the Peer that created it: for example by passing a reference to that Service object, for example within its constructor. Or by having a setter method on the Service class that allows you to do that.
But of course: that sounds like the wrong way. A service instance should be really independent of the Peers using it! In other words: if it really makes sense that a Service knows one (or multiple?!) peers, then the Service class needs a field to "remember" that relationship. But at least the example given here rather suggests that your Service should not at all know (or care) about the Peers using it!

Unable to access protected method in subclass [duplicate]

This question already has answers here:
Understanding Java's protected modifier
(6 answers)
Closed 7 years ago.
i cannot access a protected method in a subclass (in same package).
I am using spring-jms API's , DefaultMessageListenerContainer class.
In my code, i have an instance of DefaultMessageListenerContainer class, and i am trying to invoke getBeanName() method on that object, but in eclipse it says,
"The method getBeanName() from the type AbstractJmsListeningContainer is not visible"
As per javadoc ,this getBeanName() method is a protected method defined in superclass, 'AbstractJmsListeningContainer'.
Per my understanding, we should be able to access protected method inside subclass.
Am i missing something ?
Attaching a sample java code snippet.
The code fragment you posted is not accessing getBeanName() from within the subclass. It is trying to access it from client code. You'd have to define your own subclass to expose a public method to get to it:
class MyDefaultMessageListenerContainer extends DefaultMessageListenerContainer {
public getMyBeanName() { return getBeanName(); }
}
MyDefaultMessageListenerContainer container = new MyDefaultMessageListenerContainer();
String name = container.getMyBeanName();
Note that you can't simply override getBeanName() because it is declared final.

php redeclaring function like in java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
php function overloading
I want to redeclare function such like this:
class Name{
function a(){ something; }
function a($param1){ something; }
}
but it returns
Fatal error: Cannot redeclare Name::a()
In java it just works. How can I do this in PHP?
Use default parameters:
class Name{
function a($param1=null){ something; }
}
If no parameter is passed to Name::a() it will assign a $param1 has a value of null. So basically passing that parameter becomes optional. If you need to know if it has a value or not you can do a simple check:
if (!is_null($param1))
{
//do something
}
You won't redeclare a function. Instead you can make an argument optional by assigning a default value to it. Like this:
function a($param1 = null){ something; }
Function arguments to not uniquely identify a function. In Java the arguments are strictly defined. This allows the compiler to know which function you are calling.
But, in PHP this is not the case.
function a()
{
$args = func_get_args();
foreach($args as $value)
{
echo $value;
}
}
It's possible to create function that has no arguments define, but still pass it arguments.
a("hello","world")
would output
hello world
As a result, PHP can't tell the different between a() and a($arg). Therefore, a() is already defined.
PHP programmers have different practices to handle this single function problem.
You can define an argument with default values.
a($arg = 'hello world');
You can pass mixed variable types.
function a($mixed)
{
if(is_bool($mixed))
{
.....
}
if(is_string($mixed))
{
.....
}
}
My preference is to use arrays with defaults. It's a lot more flexible.
function a($options=array())
{
$default = array('setting'=>true);
$options = array_merge($default,$options);
....
}
a(array('setting'=>false);
Unfortunately PHP does not support Method overloading like Java does. Have a look at this here for a solution: PHP function overloading
so func_get_args() is the way to go:

Using "Adapter" pattern

How I understand, the Goal of the Adapter pattern is to call some class methods using some interface (which opened to clients). To make adapter pattern we need to implement some interface (which uses by client), and also we need to extend some class, which methods client need to call when calling interface methods.
class Adapter extends NeedClass implements PublicInterface{}
But what if we haven't interface, but have only 2 classes? For example we have some class(not interface!) which methods uses clients. Now we need to call methods of other class by making adapter class, but we cant to do this, because we cant make multiple Inheritance on the adapter class.
class Adapter extends NeedClass, PublicInterface
above code doesnt work.
What we can do in this case?
You can has an instance of NeedClass in Adapter and call it, when you need. So you extend only from PublicInterface.
public class Adapter extends PublicInterface {
private NeedClass needClass;
#Override
public void doSomething() {
needClass.doSomethingElse("someParameter");
}
}
You can use a composition instead of inheritance. Add a field to Adapter class of type NeedClass:
public class Adapter extends PublicInterface {
private NeedClass needClass;
}
Then inside Adapter methods delegate execution to needClass field.
From what i have understood the Adapter Pattern.
it is helpful when dealing with the third part codes such as API which is/ are subject to changes any time and my likely to break your code if implemented direct.
For example : Using Paypal in your site for payment online.let's assume the Paypal uses the method payMoney() for payment. and after sometime they decide to change the method to something else let's say sendMoney(). This is likely to break your code if implemented directly, with the use of Adapter Design pattern this can be solves as follow
the third part code => Paypal
class Paypal {
public function __construct(){
// their codes
}
public function payMoney($amount){
// the logic of validating
// the $amount variables and do the payment
}
}
so implement it directly in the code as below will break the code
$pay = new Paypal();
$pay->payMoney(200);
using adapter will save numbers of hours and a complex work of updating the code from payMoney() to sendMoney() in every where that the API scripts has been implemented. Adapter enable update in one place and that's it.
Let see it.
class paypalAdapter {
private $paypal;
// Paypal object into construct and check if it's pa
// Paypal object via type hint
public function __construct(PayPal $paypal) {
$this->paypal = $paypal;
}
// call the Paypal method in your own
//custom method that is to be
// implemented directly into your code
public function pay($amount) {
$this->paypal->payMoney($amount);
}
}
so it is like that and there you can go and use the PaypalAdater directly into the code as follow;
$pay = new PaypalAdapter(new Paypal);
$pay->pay(200);
So in future when the Vendor(Paypal) decide to use sendMoney instead of payMoney what to be done is to open the PaypalAdapter class and do the following in the pay($amount) method:
// SEE THIS METHOD ABOVE TO OBSERVE CHANGES
// FROM $this->paypal->payMoney($amount);
// TO $this->paypal->senMoney($amount);
public function pay($amount) {
$this->paypal->sendMoney($amount);
}
After this minor change in one place, everything works well as before.

Categories