Generic parameter type that accepts void - java

I am trying to create an API for an open source project I am working on, and I have hit a speed bump in trying to extend the API while keeping the semantics consistent with the current API. What I desire is to be able to define a method signature with a generic parameter that accepts the result of calling any method signature. By "any", that is meant to include void methods. I already know that you cannot directly define parameter types of void -- please do not repeat the obvious fact. What is not obvious is whether there is any trick by which a void method call can be provided as an argument to a method (i.e., and ignored).
Back story so this makes a little more sense why I would want to do such a thing, and what my design goal and constraints are, in case the above is impossible (as I fear it is):
My current API defines a very repeatable pattern of methods like this:
public <T,V> Function<T,V> functionFor(V ignoredRetVal) {...}
public <T> Predicate<T> predicateFor(V ignoredRetVal) {...}
public <T> Filter<T> filterFor(V ignoredRetVal) {...}
As the names imply, the parameters are ignored and are not even used in the implementation. In usage, ignoredRetVal is replaced with a method call to a dynamic proxy. Since parameters are evaluated before the method is invoked, this dynamic proxy method is invoked before the outer function (functionFor or predicateFor, etc.). The dynamic proxy invocation records the Method (or method chain) called, and converts this into a Function object (Guava) or other function-like object from multiple functional libraries.
What I am trying to do now is create a similar semantic that captures method invocations that are used for side-effects only without any need for a return type (such as Functional Java's Effect. If a non-void return type is provided, it is ignored. If a void return type is provided, it too is ignored and accepted. The key is that the semantics must somehow force the proxy method to be invoked before another method that extracts the intercepted proxied method calls. And since we are only interested in side effects, candidate methods are likely to include void methods. Ideally it would look something like:
public <T, V> Effect<T> effectFor(V ignoredRetVal) {...}
(which already works for non-void return types) and it could be used as follows:
Effect<MyClass> effect1 = effectFor (proxyOfMyClass.nonVoidMethod());// OK :-)
Effect<MyClass> effect2 = effectFor (proxyOfMyClass.orVoidMethod()); // Problem!!
As I have said, I'm afraid the semantic I am looking for is not directly supportable. If not, then any alternative should be close in spirit to the pattern I have established. Also, the whole goal of my API was to reduce "vertical noise" of inner class implementations, and I am not a fan of Double Brace Initializers. Whatever suggestions are offered, I am looking for a semantic that supports brevity, especially a single-statement semantic.

I don't think you'll ever be able to coerce a void into an expression, particularly if you don't like the double-brace hack.
You could follow Mockito's example in your API design. Normally, you set up an mock like this:
when(mockedInstance.someMethod()).thenThrow(new IllegalArgumentException());
But for a void, you do this:
doThrow(new IllegalArgumentException()).when(mockedInstance).someMethod();
Similarly, you can enumerate the methods of Effect<T> to make them static methods of your library.
E.g. if Effect<T> has doSomething() then you would invert it, like
doSomething().onEffectFor(proxyInstanceOfA).methodA();
But this assumes that the relevant methods of Effect<T> don't return a value themselves.
If that's not an option, and you need the Effect<T>, you could make it stateful, something like this:
VoidEffect<MyType> effect = effectForVoid(proxyOfMyClass);
effect.on().myVoidMethod();
Where VoidEffect<T> implements Effect<Void>, and on() returns the proxy passed in (or a different proxy). Then you would want to throw an IllegalStateException if on() wasn't called before you otherwise interact with effect.

Related

Java Class.cast to most specific with method overloading

I have a code that looks like this
function a(Object m) {}
function a(BasicDbObject) {}
function a(TypeA) {}
function a(TypeB) {}
function a(TypeC) {}
.....
function b(Object m) {
// Some function using Java reflection to determine class of Object m
Class X = c(m);
a(X.cast(m));
}
Here is the problem. It always execute a(Object m) rather than a(BasicDbObject m), even it is BasicDbObject.
My end goal is to execute most closest function to the object passed.
What you are trying cannot be done, because Java is statically typed, and the method overload is resolved at compile-time, not run-time.
The only way to resolve the overload at runtime, is for the method call itself to be done with reflection.
Serious non-answer: wrong approach.
You don't use reflection to dynamically determine a type, to then figure which overloaded method to call.
Instead, use polymorphism. Meaning: don't overload, but override.
Rest assured: getting "reflection" working is hard. Getting it correct, and robust and stable is a super challenging, uphill battle.
You basically want to invent your own personal dynamic dispatch implementation. Unless you have super hard pressing reasons to do so, that is a terrible idea. Because chances are that you will get it wrong. Many many times. And even when your code is working, there will be many incidents later on, when unforeseen things happen in production.
As said: don't do this. Don't fight the language, instead use the means that the language offers you to solve such problems: an inheritance tree of classes, and polymorphic methods. Then let the JVM decide which method to invoke. Most likely, the JVM will do a much better job, compared to what you will come up with.
function a(Object m) {}
function a(BasicDbObject) {}
When methods are overloaded, it may not be intuitive to know the method which gets invoked for any set of parameters because, unlike the situation with overridden methods, the method overloading that gets invoked is determined at compile time (i.e. statically) rather than at run time (i.e. dynamically). This behavior is confusing because overriding methods is more common and this sets our expectations for method invocation.
There are some rules for doing method overloading as robustly and as simply as possible. These are all nicely enumerated in Effective Java (J. Bloch, 2nd and 3rd eds.).
Your situation is made complex because:
You have two overloadings with the same number of parameters whose types are not radically different ... and ...
The behavior of the overloadings is apparently dependent on the type of the parameter (if the behavior was identical, then you simply have one overloading forward to the other)
When this situation arises, you should try to correct it by giving the overloadings different names. It should always be possible to do this and doing so often improves the clarity and maintainability of the code.
If this can't be done for any reason, then the best workaround is to replace the overloadings with a method that accepts the most general parameter type and which invokes helper methods based on the most specific type of the passed argument.
So instead of the above, you can get the behavior you want by using...
public Function a(Object m) {
if (m instanceof BasicDbObject) return doDbObject(m);
if (m instanceof OtherDbObject) return doOtherDbObject(m);
return doGenericObject(m);
}
Note that this isn't the code that you would use when Java adopts pattern matching in the language. Note also that the effect of this code is to give your overloadings different names, but the selection of the distinct method is made at run time using instanceof comparisons rather than at compile time by simply using a distinct name.
TLDR; if you are doing method overloading in a circumstance in which the parameter types are not (or may not be) radically different then you are better off not overloading and using distinct method names.

Why can a void method in C++ return a void value, but in other languages it cannot?

This program compiles and runs in C++ but doesn't in a number of different languages, like Java and C#.
#include <iostream>
using namespace std;
void foo2() {
cout << "foo 2.\n";
}
void foo() {
return foo2();
}
int main() {
foo();
return 0;
}
In Java this gives a compiler error like 'Void methods cannot return a value'. But since the method being called is a void itself, it doesn't return a value. I understand that a construct like this is probably prohibited for the sake of readability. Are there any other objections?
Edit: For future reference, I found some a similar question here return-void-type-in-c-and-c
In my humble opinion this question isn't answered yet.
The reply 'Because it says so in the specification, move on' doesn't cut it, since someone had to write the specification in the first place. Maybe I should have asked 'What are the pros and cons of allowing returning a void type like C++'?
It's because of the possibility of its usage in templates. C# and Java forbid void as a type argument, but C++ permits it to allow you to write template code like this:
template<typename T, typename TResult>
TResult foo(T x, T y)
{
return foo2(x, y);
}
If void methods weren't allowed to return a void expression, this template instantiation would be impossible if TResult was void. If that were the case, you would need a separate template definition if you ever wanted TResult to actually be void.
For example, remember how in C# there are two sets of generic general-purpose delegates, namely Func<> and Action<>? Well, Action<T> exists precisely because Func<T, void> is forbidden. The C++ designers didn't want to introduce situations like this wherever possible, so they decided to allow you to use void as a template argument -- and the case you found is a feature to facilitate exactly that.
(Allow me to write the rest in a pretend-Q&A format.)
But why do C# and Java not allow a similar construct?
First, realize how generic programming is made possible in those languages:
C# and Java generics work by parsing a generic type (or method) definition and making sure it is valid for the generic constraints/bounds you have provided.
C++ templates are a search-and-replace mechanism with a powerful metaprogramming language around them. They are not required to make sense in the absence of specific template arguments -- they go from the "template metalanguage" to the "C++ language" (so to speak) only when they get their hands on actual arguments.
Why pick one approach of implementing generic programming over the other?
The generics approach maintains the nominal typing of the rest of the language. This has the advantage of allowing the (AOT) compiler to do static analysis, type checking, error reporting, overload resolution and eventually code generation once.
The templates approach is essentially duck typing. Duck typing in a nominally typed language doesn't have the advantages described above, but it allows you more flexibility in the sense that it will permit potentially "invalid" things ("invalid" from the point of view of a nominal type system) as long as you don't actually mention those invalid possibilities anywhere in your program. In other words, templates allow you to express a larger set of cases uniformly.
Okay, so what would C# and Java need to do to support void as a valid generic argument?
I would have to speculate to answer this, but I'll try.
At the language level, they would have to waive the notion that return; is valid only in void methods and always invalid for non-void methods. Without this change, very few useful methods could be instantiated -- and they would all probably have to end with recursion or an unconditional throw (which satisfies both void and non-void methods without returning). So to make this useful, C# and Java would also have to introduce the C++ feature of allowing you to return void expressions.
Okay, let's assume you have that and now you can write code like this:
void Foo2() { }
void Foo()
{
return Foo2();
}
Again, the non-generic version is as useless in C# and Java as it is in C++. But let's move on and see its real usefulness, which is in generics.
You should now be able to write generic code like this -- and TResult could now be void (in addition to all the other types that were already permitted):
TResult Foo<T, TResult>(T a)
{
return Foo2(a);
}
But remember that in C# and Java, overload resolution happens "early", rather than "late". The same callee will be chosen by the overload resolution algorithm for every possible TResult. And the type checker will have to complain, because you're either returning a void expression from a possibly non-void method or you're returning a non-void expression from a possibly void method.
In other words, the outer method can't be generic, unless:
The callee is also generic and its return type is defined by a generic type parameter that matches that of the outer method.
Overload resolution in generic types and methods is postponed until actual type arguments are made available, so that we can pick a correct non-generic method at the call spot.
What if we went with the first option - make the callee's return type generic and move on?
We could do that, but it simply pushes our problem to the callee.
At some point, we would need some way to "instantiate" some kind of void instance and optionally be able to receive it somehow. So now we would need constructors for void (although every void method could count as a factory method, if you squint) and we would also need variables of type void, possible conversions from void to object, and so on.
Basically, void would have to become a regular type (e.g. a regular empty struct) for all intents and purposes. The implications of this aren't terrible, but I think you can see why C# and Java avoided it.
What about the second option - postpone overload resolution?
Also entirely possible, but note that it would effectively turn generics into weaker templates. ("Weaker" in the sense that C++ templates aren't restricted to typenames.)
Again, it wouldn't be the end of the world, but it would involve losing the advantages of generics that I described earlier. The designers of C# and Java clearly want to keep those advantages.
Sidenote:
In C#, there is one special case I know of, where binding happens after the validation of the generic type definition. If you have a new() constraint on a T and you attempt to instantiate a new T(), the compiler will generate code that checks whether T is a value type or not. Then:
For value types, new T() becomes default(T) -- remember that C# default struct constructors aren't really constructors in the CLR sense.
For reference types, Activator.CreateInstance is called, which is an indirect constructor invocation using reflection.
This particular case is very special because, even though it has completely postponed method binding to the runtime, the compiler can still perform static analysis, type checking and code generation once. After all, the type of the expression new T() is always T and a call to something that has an empty formal parameter list can be trivially resolved and verified.
According to the Java Language Specification §14.17:
A return statement with no Expression must be contained in one of the following, or a compile-time error occurs:
A method that is declared, using the keyword void, not to return a value (§8.4.5)
...
A return statement with an Expression must be contained in one of the following, or a compile-time error occurs:
A method that is declared to return a value
...
So, by declaring that a method is void, you are saying that it returns no value, so you are limited to using a return; statement with no expression.

Is it possible to convert method reference to MethodHandle?

Is it possible to convert a method reference (e.g. SomeClass::someMethod) to a MethodHandle instance? I want the benefits of compile-time checking (ensuring that the class and method exists) as well as the ability to introspect the method using the MethodHandle API.
Use-case: I've got code that needs to execute if and only if the request was not triggered by a specific method (to avoid endless recursion). I want a compile-time check to ensure the class/method exists but a runtime check to compare the caller to the method.
So to recap: Is it possible to convert a method reference to a MethodHandle?
Well, if you can afford the additional overhead and security implications, you can use a Serializable functional interface and decode the serialized form of the method reference instance to find the target like demonstrated in this answer or brought up again with this question and its answers.
However, you should really rethink your software design. “Avoiding endless recursion” shouldn’t be fixed by decoding some kind of parameter object, especially not if your assumption is, that this actual argument value represents the caller of your method. How would you ever enforce this strange relationship?
Even a simple code change like referencing a method which delegates to the other method would break your check. Here is a simple example showing the subtle problems with your approach:
public class SimpleTest {
public static void main(String... arg) {
run(SimpleTest::process);
}
static void run(BiConsumer<Object,Object> c) {
c.accept("foo", "bar");
}
static void process(Object... arg) {
Thread.dumpStack();
}
}
When running this program it will print something like:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1329)
at SimpleTest.process(SimpleTest.java:16)
at SimpleTest.lambda$MR$main$process$a9318f35$1(SimpleTest.java:10)
at SimpleTest$$Lambda$1/26852690.accept(Unknown Source)
at SimpleTest.run(SimpleTest.java:13)
at SimpleTest.main(SimpleTest.java:10)
showing that the method reference within the generated instance is not the expected SimpleTest::process but instead SimpleTest::lambda$MR$main$process$a9318f35$1 which will eventually invoke process. The reason is that some operations (here varargs processing) are not performed by the generated interface instance but a synthetic method instead, just like you had written run((a,b)-> SimpleTest.process(a,b)). The only difference is the name of the synthetic method.
You shouldn’t design software relying on such fragile introspection. If you want to avoid recursion, a simple ThreadLocal flag telling whether you are already inside your specific method would do the job. But it might be worth asking yourself why your API is provoking endless recursion in the first place; there seems to be something fundamentally wrong…

Java: When to use fields vs. arguments?

My current IVR app uses a wrapper class with several methods to call a web service and then parse its results. Each class has a single "invoke" method which calls the web service, and then calls subsequent submethods to break up the parsing into logical chunks.
Whenever a new input argument is needed in one or more of the submethods, the previous developer would add it as an argument on the invoke, and then add it as an argument on the submethods.
Is this the proper way to do this, or would it be better to set a field on the class, and then reference that whenever necessary?
Instead of:
invoke (oldField1, oldField2, newField1)
submethod1 (results, oldField1, oldField2, newField1)
submethod2 (results, oldField1, oldField2, newField1)
Should it be:
invoke(oldField1, oldField2, newField1){
OldField1=oldField1
OldField2=oldField2
NewField1=newField1
}
submethod1(results)
submethod2(results)
Or even:
new (oldField1, oldField2, newField1){
OldField1=oldField1
OldField2=oldField2
NewField1=newField1
}
invoke()
submethod1(results)
submethod2(results)
Thanks!
The first solution allows making the object stateless, and allows using a unique instance for all the invocations, even in parallel.
The third one allows making the object stateful but immutable. It could be used for several invocations using the same set of fields, even in parallel (if made immutable).
Both of these solutions are acceptable. The less state an object has, the easiest it is to use it, particularly in a multi-thread environment.
The less mutable an object is, the easiest it is to use it.
The second one makes it a stateful mutable object, which can't be used by several threads (without synchronization). It looks less clean than the other two to me.
My general rule is to avoid statefulness in a service-oriented class whenever possible. Although Java doesn't really support functional programming per-se, the simplest and most scalable implementation is your first approach, which uses no member variables.
If your goal is to avoid frequent changes to method signatures, you could try to use a more generic field encapsulation:
public class Invoker {
public static void invoke(ResultContainer result, List<String> parameters) {
submethod1(result, parameters);
submethod2(result, parameters);
}
}
I would also recommend that you take a look at the Decorator design pattern for more ideas.
It depends on if your argument is data or identifying a mode/switch.
I suggest one argument for the data structure type and another argument that contains the enum types of different operations.
And then based on your enum type or mode of operation you can choose a strategy on which class to execute.
To restrict this increasing argument approach, you could provide an interface. And force the implementation to adhere to that.

Protected "stub" methods used only for overriding purposes considered good practice or not?

Sometimes when I extend one of my own classes, I want to (for the purpose of the subclass) "inject" one or two lines of code in the middle a method in the super class.
In these cases I sometimes add a call to an empty protected method for the subclass to override.
public void superClassMethod() {
// some fairly long snippet of code
doSubclassSpecificStuff();
// some other fairly long snippet of code
}
// dummy method used for overriding purposes only!
protected void doSubclassSpecificStuff() {
}
When doing this several times in the same class I must say it looks quit awkward / ugly so my questions:
Is this way of "opening up" for subclasses to "inject" code in the middle of methods considered good practice or not?
Is the pattern (anti-pattern?) called something?
Has it been used in any well known API / library? (Note that I'm talking about non-abstract classes.)
Are there any better alternatives?
The only alternative I can come up with is to use something like the command pattern and have a setMiddleOfMethodHandler(SomeRunnableHandler), and call handler.doSubclassSpecificStuff() instead of the dummy-method. It has a few drawbacks as I see it though, such as for instance not being able to touch protected data.
You've just discovered the Template method design pattern. Note though that normally the methods that comprise the individual steps are abstract (rather than empty and protected) so that subclasses must override them.
There is the Template method pattern. The idea there is that much of the work is common, except for a few bits, which are handled by a subclass implemented method.
Yes, this is a legitimate way to do things; I've used it myself.
The only problem I can see is not the specific technique, but the fact that you are using subclasses of concrete (read: non-abstract) classes at all. Subclassing concrete classes has many subtle problems, so I would recommend to avoid it altogether. See e.g. http://en.wikipedia.org/wiki/Liskov_substitution_principle for an explanation of what you must do to properly subclass a class, and the problems involved. Also, in "Effective Java" Block recommends using composition (Item 16).
Another approach (that avoids subclassing) would be to use Dependency Injection. Your method would accept a parameter of a type that implements the interface ISpecificStuff, which specifies a method doSubclassSpecificStuff():
public void superClassMethod(ISpecificStuff specificStuff) {
....
specificStuff.doSubclassSpecificStuff();
....
}
That way, any caller can decide what the method should do. This avoids the need for subclassing. Of course, you could inject via a constructor, if you need it in more than one method.
It looks fishy to me. I think the reason you're ending up having to do this is a design flaw. Your method that needs to be "split" probably does too much. The solution would be to break it up in steps, and give that "doSubclassSpecificStuff" step a specific meaning.
For ex.:
void Live()
{
BeBorn();
DoCrazyStuff(); // this can be made protected virtual
Die();
}
Yes, it's perfectly fine. This is an example of the Template Method pattern, where you use inheritance to define a method that maintains a known "skeleton", but can have custom logic.
public abstract class Ancestor
{
protected virtual void CanOverrideThisStep(){...}
protected abstract void MustDefineThisStep();
protected sealed void MustDoExactlyThis(){...}
private void HideThisStepFromEveryone(){...}
public sealed void TemplateMethod()
{
...
CanOverrideThisStep();
...
MustDoExactlyThis();
...
MustDefineThisStep();
...
HideThisStepFromEveryone();
}
}
Inheritors of Ancestor above must define a body for MustDefineThisStep(), and may at their option override CanOverrideThisStep(), but cannot touch MustDoExactlyThis(), HideThisStepFromEveryone, or the TemplateMethod driving function itself. However, except for HideThisStepFromEveryone, all the submethods are available to child classes, so a child may use MustDoExactlyThis() in the implementation of MustDefineThisStep().
This is very common; such constructions are the reason OO languages have such access modifiers such as these at their disposal. The pattern is very useful for workflows, file processing, and other tasks that are generally the same but have slightly different implementation details.
I routinely use this technique as a way to handle special cases. I'll write things like this:
public void foo()
{
theData=getTheData();
preprocessDataHook(theData);
putTheData(theData);
}
protected void preprocessDataHook(SomeObject theData)
{
// Nop. Available for subclasses to override.
}
A subclass that does not need to preprocess the data can then just not override this function. A subclass that does need to preprocess can override the function.
If we expected that all or most subclasses would need to preprocess, then this should be an abstract function to force the programmer to implement it, or make a conscious decision to do nothing. But if it's just an occassional subclass that needs to do something here, I think this is a perfectly valid approach.

Categories

Resources