I have a class that performs a business function and there are multiple methods being called by the entry-point method.
public class Tool
{
public void runTool()
{
methodA();
methodB();
methodC();
printToolSummary();
}
}
Each of these methods method* called perform a specific sub-function and I would like to collect the results/attributes of interest in each of these methods into a summary object. Its not a single value to be returned by these method* methods.
I was thinking of a single object that contains all the attributes of interest, pass this object to each method and let that method set the attribute, but somehow it doesn't sound right to work with a mutable object as there is no way to prevent methodA from updating an attribute it shouldn't, or am I worrying too much?
If you're concerned about the methods touching some part of the object that they shouldn't then the object you're passing into the methods should implement several interfaces with each one only exposing the properties that you want the acting method to touch.
So methodA could expect a class of type A and methodB could expect a class of type B where A and B are interfaces...
Otherwise there's not really anything wrong with your approach and it's fairly common.
How about using a complex object that contains sub-classes for each of your methods. For example:
public class ResultA { // some attributes for Method A }
public class ResultB { // some attributes for Method B }
public class ResultC { // some attributes for Method C }
public class Result {
private ResultA resultA;
private ResultB resultB;
private ResultC resultC;
}
Related
I have a software specification document for a specific library in java which helps collecting data from a biosensor and has a class called 'Patch'. The document specifies:
Following is the constructor of Patch class:
Patch(JSONObject options, (JSONObject)->onDiscovery,(JSONObject)->ondata,(JSONObject)->onStatus)
Where
JOSNObject options: options settings for the object
(JSONObject)->onDiscovery: Callback for receiving the sensor info as a JSONObject,
(JSONObject)->ondata: Callback for receiving the sensor data as a JSONObject,
(JSONObject)->onStatus: Callback for receiving the global errors as a JSONObject
It should be called as
Patch patch=newPatch(jsonConfigObject, discoveryObject, streamObject, status);
The concerned fellow stated that these callbacks shall be just lambda expressions.
Now what I understand is:
Constructor takes 4 args:
An empty JSON object,
Callback function reference
Callback function reference
Callback function reference
Am new to Callback implementation so am not able to figure out:
how shall I implement this one in my code?
Do I have to create the functional interfaces for each of those callback methods?
Lets say I have just imported the library, what shall I do next?
The objective of lambda expressions is to denote methods that the Patch-object can call (back) at certain events. In contrast to other programming languages it was not possible to pass functions as parameters to constructors or methods in Java. Thus it was necessary to create an object of a class that implements a certain interface (or is otherwise known to have a certain method by type) and to pass it to the method or constructor as a parameter. The method can then be called at the passed object when the event occurs.
The functional interface is already there. You do not need to create it by yourself. It has been already used in the signature of the constructor of Patch (the types of the last three parameters to the constructor). Functional interfaces are types which have exactly one abstract method that has to be overridden.
Lets suppose the functional interface looks like this:
interface Callback { // could of course have a different name
public void call(JSONObject o);
}
It is not necessary to add the #FunctionalInterface-annotation. It would only prevent the interface from later modifications, namely adding further abstract methods.
It seems reasonable to assume that the abstract method does not have a return value (but you need to check this. When you use lambda expressions you do not need to know what the actual method name (here call) is.
Although most handy it is not necessary to call the constructor with lambda expressions for the last three parameters. Other possibilities include a method reference (using ::), anonymous classes, and instantiating a newly defines class.
Of course you need to know what should happen when the three events occur. Lets say that you have already three methods that provide the necessary functionality. Probably a JSONObject that contains information about the event is necessary to do something useful.
class Main {
static void onDiscovery(JSONObject o) {...}
static void onData(JSONObject o) {...}
static void onStatus(JSONObject o) {...}
}
It is not necessary that the three methods have exactly these names nor that they are static.
In the main method of this class (or somewhere else) could happen:
public static void main(String[] args) {
JSONObject o = // ...
Patch p = new Patch(o,
(x) -> Main.onDiscovery(x), // (1) lambda expr. (Main. can be omitted)
Main::onData, // (2) method reference
new Callback() { // (3) anonymous inner class
public void call(JSONObject x) {
Main.onStatus(x);
}
});
//...
}
(1)-(3) show alternative ways to pass an object of type Callback.
(1) has the advantage that shorter implementations could go right here instead of calling onDiscovery(x). If you have more than one statement you need curly brackets around the statements and ";" after each statement:
(x) -> {
System.out.println("discovery event");
System.out.println(x.getXYZ());
// ...
}
(2) has the advantage to be super concise. If you do not have a static method to reference, a object reference can also be used to denote the object on which the method should be called.
(3) anonymous inner classes are would normally not be used anymore for functional interfaces. If the interface / abstract class has more abstract methods but one it is still necessary to use anonymous inner classes.
class Main {
void onData(JSONObject o) { ... }
// ...
public static void main(String[] args) {
var m = new Main();
var o = new JSONObject(); // or whatever
var p = new Patch(o,
(x) -> m.onDiscovery(x),
m::onData;
new Callback() {
public void call(JSONObject x) {
m.onStatus(x);
}
});
}
}
I have a method which adds Objects to an static list like this:
#PostConstruct
protected void registerToTransactionList() {
TransactionValidator.registerTransactionList(this);
}
registerTransactionList method just adds "this" to the static list, this method is in BalanceTransactionValidator class which extends TransactionValidator (owner of static list),the problem is all subclasses of BalanceTransactionValidator class are added to static list either,and if I override registerToTransactionList method in them like this:
#Override
#PostConstruct
protected void registerToTransactionList() {
}
It doesn't add subclasses but doesn't add BalanceTransactionValidator either. Can anybody help me on this? Please notice sublasses are overriding this method by default.
make the method private to block the visibility
private void registerToTransactionList() {
}
or make the method final to block it from been override
protected final void registerToTransactionList() {
}
There are two ways of achieving that:
Keep your method as it is; but then you have to actively check for the type of your objects before externally calling that method
Change your whole logic and make that method private
It won't help to make the method final as suggested in one of the comments - your problem is not that subclasses are overwriting that method; in essence, you have a design problem: you wish that subclasses should not invoke that method at all.
So, the only real option that makes sense here is "2.". You see, by having public method on a class that you want to be extended you are implicitly saying: it is perfectly fine to call that method; on any object that is instance of the base class (or child class!).
And in your case, that is not true: you actually do not want that the code behind this method runs for child classes. Then you shouldn't put that method in the list of public/protected methods of your base class!
Finally: you might want to step back and do some reading about good OO design. Class hierarchies do not fall from the sky: you willfully design them for a certain purpose. In other words: there is more to inheritance than just putting some "A extends B" on your class declaration. You have to understand each and every method on your B class; and how your child classes should deal with them!
EDIT: after some more thinking, I guess you are doing things "the wrong way", like:
class BaseClass {
public final void doRegistration() {
BaseClass toRegister = getObjectForRegistration();
if (toRegister != null) { ... register toRegister ...
}
protected BaseClass getObjectForRegistration() {
return null;
}
With that code, you could then put
protected BaseClass getObjectForRegistration() {
if (this instanceof ClassThatShouldBeRegistered) {
return this;
}
return null;
}
into that one class that wants to be registered. Probably there could be even nicer ways of doing so; but after some thinking I don't see how we could avoid the instanceof. But the above code should work; and it only requires specific code only in your base class and in that one class that wants to register something.
I have created an instance of an object in one of my classes for a Java program. How can I pass the same instance of that object to another class?
Would I need to do something like creating some type of a getter method in the original class to pass the object through to the other class?
To "pass" it you need a method or a constructor in the other class that can accept it:
public class Other {
// either
public Other(MyClass obj) {
// do something with obj
}
// or
public void method(MyClass obj) {
// do something with obj
}
}
Then call the constructor/method:
MyClass x = new MyClass();
Other other = new Other();
other.method(x);
There are many ways to pass the reference for one object to another object. The simplest and most common ways are:
as a constructor parameter,
as a parameter of a setter method; e.g. setFoo(Foo foo) to set the "foo" attribute, or
as an "add" method in the object being passed is going to be added to a collection; e.g. addFoo(Foo foo).
Then there are a variety of more complicated patterns where objects are passed using publish/subscribe, call-backs, futures, and so on.
Finally there are some tricks that can be used to "smuggle" objects across abstraction boundaries ... which are generally a bad idea.
You can pass the object via the constructor of the other class.
Simple Example:
Class A{
}
Class B{
A a;
public B(A obj){
this.a=obj
}
}
Let's assume you want to pass an object of class A to class B. Now you have created the object like this:
A object = new A ();
And now in your B class, you can write a method to accept a A object. It should be public and you can make it static if you like.
If you want to pass object to B, you must want to do something with it, right? So you should name your method accordingly. You probably want to assign a field of type A (Let's call this fieldA) in B. (or maybe that isn't what you want, but I'll use this for the example)
Let's look at the method:
public void setFieldA (A a) {
fieldA = a;
}
You can call this method as follows:
anObjectOfClassB.setFieldA (object);
Of course you don't need anObjectOfClassB if it is static.
This may be something common and trivial, but I seem to be having trouble finding a concrete answer. In C# there is a concept of delegates, which relates strongly to the idea of function pointers from C++. Is there a similar functionality in Java? Given that pointers are somewhat absent, what is the best way about this? And to be clear, we're talking first class here.
The Java idiom for function-pointer-like functionality is an an anonymous class implementing an interface, e.g.
Collections.sort(list, new Comparator<MyClass>(){
public int compare(MyClass a, MyClass b)
{
// compare objects
}
});
Update: the above is necessary in Java versions prior to Java 8. Now we have much nicer alternatives, namely lambdas:
list.sort((a, b) -> a.isGreaterThan(b));
and method references:
list.sort(MyClass::isGreaterThan);
You can substitue a function pointer with an interface. Lets say you want to run through a collection and do something with each element.
public interface IFunction {
public void execute(Object o);
}
This is the interface we could pass to some say CollectionUtils2.doFunc(Collection c, IFunction f).
public static void doFunc(Collection c, IFunction f) {
for (Object o : c) {
f.execute(o);
}
}
As an example say we have a collection of numbers and you would like to add 1 to every element.
CollectionUtils2.doFunc(List numbers, new IFunction() {
public void execute(Object o) {
Integer anInt = (Integer) o;
anInt++;
}
});
You can use reflection to do it.
Pass as parameter the object and the method name (as a string) and then invoke the method. For example:
Object methodCaller(Object theObject, String methodName) {
return theObject.getClass().getMethod(methodName).invoke(theObject);
// Catch the exceptions
}
And then use it as in:
String theDescription = methodCaller(object1, "toString");
Class theClass = methodCaller(object2, "getClass");
Of course, check all exceptions and add the needed casts.
No, functions are not first class objects in java. You can do the same thing by implementing a handler class - this is how callbacks are implemented in the Swing etc.
There are however proposals for closures (the official name for what you're talking about) in future versions of java - Javaworld has an interesting article.
This brings to mind Steve Yegge's Execution in the Kingdom of Nouns. It basically states that Java needs an object for every action, and therefore does not have "verb-only" entities like function pointers.
To achieve similar functionality you could use anonymous inner classes.
If you were to define a interface Foo:
interface Foo {
Object myFunc(Object arg);
}
Create a method bar which will receive a 'function pointer' as an argument:
public void bar(Foo foo) {
// .....
Object object = foo.myFunc(argValue);
// .....
}
Finally call the method as follows:
bar(new Foo() {
public Object myFunc(Object arg) {
// Function code.
}
}
Java8 has introduced lambdas and method references. So if your function matches a functional interface (you can create your own) you can use a method reference in this case.
Java provides a set of common functional interfaces. whereas you could do the following:
public class Test {
public void test1(Integer i) {}
public void test2(Integer i) {}
public void consumer(Consumer<Integer> a) {
a.accept(10);
}
public void provideConsumer() {
consumer(this::test1); // method reference
consumer(x -> test2(x)); // lambda
}
}
There is no such thing in Java. You will need to wrap your function into some object and pass the reference to that object in order to pass the reference to the method on that object.
Syntactically, this can be eased to a certain extent by using anonymous classes defined in-place or anonymous classes defined as member variables of the class.
Example:
class MyComponent extends JPanel {
private JButton button;
public MyComponent() {
button = new JButton("click me");
button.addActionListener(buttonAction);
add(button);
}
private ActionListener buttonAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// handle the event...
// note how the handler instance can access
// members of the surrounding class
button.setText("you clicked me");
}
}
}
I have implemented callback/delegate support in Java using reflection. Details and working source are available on my website.
How It Works
We have a principle class named Callback with a nested class named WithParms. The API which needs the callback will take a Callback object as a parameter and, if neccessary, create a Callback.WithParms as a method variable. Since a great many of the applications of this object will be recursive, this works very cleanly.
With performance still a high priority to me, I didn't want to be required to create a throwaway object array to hold the parameters for every invocation - after all in a large data structure there could be thousands of elements, and in a message processing scenario we could end up processing thousands of data structures a second.
In order to be threadsafe the parameter array needs to exist uniquely for each invocation of the API method, and for efficiency the same one should be used for every invocation of the callback; I needed a second object which would be cheap to create in order to bind the callback with a parameter array for invocation. But, in some scenarios, the invoker would already have a the parameter array for other reasons. For these two reasons, the parameter array did not belong in the Callback object. Also the choice of invocation (passing the parameters as an array or as individual objects) belongs in the hands of the API using the callback enabling it to use whichever invocation is best suited to it's inner workings.
The WithParms nested class, then, is optional and serves two purposes, it contains the parameter object array needed for the callback invocations, and it provides 10 overloaded invoke() methods (with from 1 to 10 parameters) which load the parameter array and then invoke the callback target.
Check the closures how they have been implemented in the lambdaj library. They actually have a behavior very similar to C# delegates:
http://code.google.com/p/lambdaj/wiki/Closures
Relative to most people here I am new to java but since I haven't seen a similar suggestion I have another alternative to suggest. Im not sure if its a good practice or not, or even suggested before and I just didn't get it. I just like it since I think its self descriptive.
/*Just to merge functions in a common name*/
public class CustomFunction{
public CustomFunction(){}
}
/*Actual functions*/
public class Function1 extends CustomFunction{
public Function1(){}
public void execute(){...something here...}
}
public class Function2 extends CustomFunction{
public Function2(){}
public void execute(){...something here...}
}
.....
/*in Main class*/
CustomFunction functionpointer = null;
then depending on the application, assign
functionpointer = new Function1();
functionpointer = new Function2();
etc.
and call by
functionpointer.execute();
Given two java classes, A and B, where A is usually instantiated via B, such as:
A myA = B.createA();
Can I create a subclass of A (let's call it SubA) and somehow have it be instantiated by the B.createA() method?
(Note that I cannot modify A and B....)
I know that not all instances of A are instances of SubA, thus I cannot do this:
SubA mySubA = B.createA();
Similarly, I cannot cast it like this either:
SubA mySubA = (SubA) (B.createA());
for the same reason -- it will get a ClassCastException.
Am I being dense and forgetting something fundamental, or is there no way to do this?
(Late addition: I'm so sorry, I should have mentioned that A and B have roughly 50 methods each, and all I want to do is add a single property to SubA, along with a getter and a setter. I'd really rather not implement all 50 of A's methods to invoke the corresponding method in the superclass's object.)
It sounds like like what you'd really like is to modify the behavior of both the original A and B. In that case, you could try extending both classes (where the extension of B is purely to specify a slightly different factory method for creating SubAs).
class SubA extends A {
/** This is the one special aspect of SubA justifying a sub-class.
Using double purely as an example. */
private double specialProperty;
public double getSpecialProperty() { return specialProperty; }
public void setSpecialProperty(double newSP) { specialProperty = newSP; }
public SubA() {
super();
// Important differences between SubAs and As go here....
// If there aren't any others, you don't need this constructor.
}
// NOTE: you don't have to do anything else with the other methods of
// A. You just inherit those.
}
class SubB extends B {
// Purely for the purposes of a slightly different factory method
public A createA() {
return new SubA();
}
// Or if you need a static method
// (this is usually instead of the first choice)
public static A createA() {
return new SubA();
}
}
Note that at this point, you could create one of your SubB factory objects and make it look like the original B like so:
B myNewB = new SubB();
A myA = myNewB.createA();
Or, if you're using the static factory instead, it isn't quite as close a match (but it's close).
A myA = SubB.createA();
Now, if you really need to do something with the sub-property, you'll have access to it via the child interface. I.e., if you create the object like so:
SubA mySubA = SubB.createA();
mySubA.setSpecialProperty(3.14);
double special = mySubA.getSpecialProperty();
Edit to discuss "Late addition":
At this point, your SubA object should be exactly what you want. It will inherit the 50 methods from the parent (A) and you can add your additional property to the child, plus the getter and setter. I changed the code above to illustrate what I mean.
This is usually done via a proxy:
class SubA extends A {
private A proxiedClass;
public SubA(A a) {
proxiedClass = a;
}
public int anyMethodInA() {
return proxiedClass.anyMethodInA();
}
}
...
SubA mySubA = new SubA(B.createA());
Doing this manually is rather verbose, so most people use some kind of a AOP library (like AspectJ) to only intercept method calls they are interested in.
You could create a wrapper around it, with SubA having a constructor that takes A as the parameter.
Like this:
SubA mySubA = new SubA(B.createA());
Since all instances of SubA are instances of A, you could then assign it to your existing A variable and override any necessary methods.
A myA = new SubA(B.createA());
I can't think of any other clean way of doing it.
If you are just wanting to add a field to A without object oriented such as changing behaviour, you could add it as an "external field". Use a WeakHashMap to map from instance of A onto the field value (just so long as the field value doesn't directly or indirectly reference A or you'll have an object life time contention issue):
private static final Map<A,FieldType> map =
new java.util.WeakHashMap<A,FieldType>(); // thread-safe from 1.6, IIRC
public static FieldType getField(A a) {
return map.get(a);
}
public static void setField(A a, FieldType value) {
map.set(a, value);
}
Really we should be using WeakIdentityHashMap, but it doesn't exist in the Java library!