API design - Is it a good practice to dictate method order? - java

public abstract class A {
private int result=-1;
public void final doExecuteMySpecialAlgorithm() {
result=0;
//do something here and get a new result
//it won't be -1.
}
public int getResult() {
if(result==-1)
throw new RuntimeException("Invoke my special algorithm first!");
return result;
}
}
Isn't getResult method a bad design - It is forcing user to invoke another method before it is invoked? How would you workaround this? Would your rather return -1 or say null (in case of an object type) and let the caller figure out what to do will a null return? or if you are sure that it won't be null, but for the return to be not null, you would have to invoke another method before invoking getResult method, would you just throw a RuntimeException? (or a checked exception?)

There's two ways here. Either make it synchronous (i.e. doExecuteMySpecialAlgorithm actually returns the result) or asynchronous.
The first is obvious, the second can be accomplished by returning a Future object for example. Either way, the caller doesn't need to think which is the proper order to call methods.
In some cases it may be alright to enforce the calling order of methods (such as the doFinal method in crypto classes), but you should still avoid making the code in a way that the user has to think carefully about how he's going to call your methods. Obviously he needs to know what to call, but if he needs to call 5 methods in a specific order, it probably means there should be only 1 method.
I mean after all, if you want to force the caller to call method1(), method2(), method3() in order, you should really make him call method(), which inside calls private methods method1(), method2() and method3(). That way you have the code well structured, but the caller can't fudge things up by calling the methods in the wrong order.

In your example I'd do the following:
public abstract class A {
private int result=-1;
public void final doExecuteMySpecialAlgorithm() {
result=0;
//do something here and get a new result
//it won't be -1.
}
public int getResult() {
if(result==-1)
doExecuteMySpecialAlgorithm();
return result;
}
}
This way a user can do the 'special' algorithm first, or if they 'forget' to, you (as the API writer) catch it for them and do this (instead of throwing an error).
Doing this makes your object do the work for you (object oriented design), of course this is YOUR API design, and I would assume that there would be extensive documentation dictating that if I call getResult that I must first call doExecuteMySpecialAlgorithm ... whatever you choose to implement YOU must document that the user is ordered to call function X before function Y or undefined behavior might result (or throw an error).

Related

Expecting PreconditionError but got NullPointerException

I have a class Natural with a precondition before the constructor method (notice the requires).
public class Natural {
private int data;
#Requires("n != null")
public Natural(Natural n) {
this(n.data);
}
}
This is the test for that Precondition. It tests the constructor for a null input.
#Test(expected = PreconditionError.class)
public void testConstructorWrong2() {
Natural n = new Natural(null);
}
The test should pass, because this test expects a violation of the Precondition. But I am getting NullPonterException instead.
As stated on the Cofoja page:
However, a very important distinction is that constructor preconditions are checked after any call to a parent constructor. This is due to super calls being necessarily the first instruction of any constructor call, making it impossible to insert precondition checks before them. (This is considered a known bug.
The above probably applies to this as well as super. The #Requires condition can only be checked after the call to this(n.data); because Java won't allow anything to come before it. And so, the call to n.data throws a NullPointerException before the annotation even has a chance to check the precondition.
If you still want to check the precondition, you will have to remove the call to this(...) and initialize the object directly
#Requires("n != null")
public Natural(Natural n) {
this.data = n.data;
}

What to return when generic methods returns 'nothing' but null can't be returned?

Suppose I have a library method like this (very abbreviated):
public static <V> Optional<V> doSomethingWith(Callable<V> callable) {
try {
return Optional.of(callable.call());
} catch (Exception ex) {
// Do something with ex
return Optional.empty();
}
}
And I want to something that doesn't return a value, like:
Library.</*What1*/>doSomethingWith(() -> {
foo();
return /*what2*/;
});
My first instinct for a generic method that doesn't return a value is making the type Void and returning null, however because the result gets wrapped in an Optional this would throw an exception.
What are reasonable placeholders for /*What1*/ and /*what2*/ that don't look totally random like Integer and 0?
[edit]
I'm trying to avoid Optional.ofNullable because empty is used here to indicate that callable.call() did not complete normally.
If you need a type hint for a generic parameter that will never be used you can use Void, the JDK does this too in some cases, e.g. when converting Runnable into CompletableFuture<T> it uses Void for T.
If you use Optional.ofNullable then you can just return null for what2, which is the only valid value for Void.
[edit] I'm trying to avoid Optional.ofNullable because empty is used here to indicate that callable.call() did not complete normally.
Then you're using the wrong tool for the job. CompletionStage or CompletableFuture has the right semantics.
I usually use Boolean.TRUE to mark success, but you could return Void.class as well. Both are cheap in the sense that not every return creates a new object to be discarded. Though Class<Void> is not just Void it may serve the purpose of labelling something as void just as well.
As already mentioned you could also create your own Result-class/-enum.
Or you could of course return Optional.<Void>nothing(), too. This would result in some Optional<Optional<Void>>, but also do the trick.
If you think all of the above is ugly, I fear that the API probably isn't to well tailored to your needs. Raise an issue/pull request or look for something else.
You could also create your own type similar to Void
public class Result {
public static final Result OK = new Result();
private Result(){}
}
and then return Result.OK.
You can also enhance this type to represent also errors, if you need.
But maybe using java Void is preferable if you don't need anything special.
Use Void for the return type, which is the logical choice for "nothing", but actually return an instance of Void.
Although the javadoc for Void says it's:
...an uninstantiable placeholder class...
You can nevertheless instantiate it:
try {
Constructor<Void> c = Void.class.getDeclaredConstructor();
c.setAccessible(true);
return c.newInstance();
} catch (Exception perfunctory) {
return null; // won't happen
}

How to determine where method was called

I provide an API and need to know, where methods of the API were invoked. I could of cause use reflection or the thread stacktrace, but that would include a lot of runtime cost.
I do not need the exact class name, a unique reference per invocation would be sufficient. In C I would normally use the preprocessor to automatically add __FILE__ and __LINE__ to the method invocation.
Is there a method in Java (besides code generation) to get a unique caller identification with low runtime cost?
One solution would be to have a cached Throwable which is passed in.
class StackPoint {
Throwable stack;
public Throwable getStack() {
if (stack == null)
stack = new Throwable();
return stack;
}
}
public void methodToCall(StackPoint sp) {
Throwable t = sp.getStack();
}
static final StackPoint one = new StackPoint();
methodToCall(one); // Have to remember to give each line a different StackPoint.
Note: if the method which calls this caller changes, you only record the first one ever.
There isn't a standard pattern and it is likely that if you want this to be efficient the caller will need to pass a unique id. The closest you can do is use is a lambda.
public void methodToCall(Runnable run) {
Class id = run.getClass();
}
You can call it like this
methodtoCall(()->{});
This will create a different class for each place it is called, even if it appears multiple times on the same line. It creates no garbage as it reuses the same object each time. You could make this shorter with
void methodToCall(IntFunction fun) {
}
and call
methodToCall(a->1);
As something asynchroneous is involved, split the call up, and let the API return the ID.
Ticket callTicket = api.call(params);
Logger.getLogger(getClass().getName(), Level.FINE, callTicket);
Result result = callTicket.get();
Above having a result returned (synchroneously) is probably not the case with your code. Your code will get the result delived elsewhere. But that could be a ticket system too.

return void in a void method?

I know I can do this:
void someMethod(){
return;
}
but I get a syntax error on
void someMethod(){
return void;
}
Why is the latter not allowed? It makes more sense to me.
Edit: I know what a void method is, and that I don't have to return from it at all(and probably shouldn't, in most cases) but I don't understand why I can't return void from a void method. In my opinion, there should be no keyword in the method declaration (like constructors) if the you are able to write return;.
I think both are to be shunned. I prefer this:
void someMethod() {
// do stuff; no return at bottom
}
I'd be willing to be that you'd find lots of methods in the JDK source code that look like this.
When you declare a method as void, you're saying that the method does not return a value. Attempting to return a value, therefore, is illegal. Additionally, return void; has a syntax error because void is not (indeed, cannot be) the name of an in-scope variable.
void is a type, not an expression, so trying to write return void is the same as trying to write return int: syntactically invalid.
When you call return void;, you are using a reserved keyword in the incorrect manner. Since it would not expect the keyword void in that manner, it would cause an error.
The Void class is an uninstantiable placeholder class to hold a
reference to the Class object representing the Java keyword void.
If you would prefer to return something, then you can return null; by parameterizing a type Void like in this answer, but that's unconventional. Best bet is to omit return altogether or just say return;.
return x; indicates that control is leaving the method and that its result is the value of x.
return; indicates that control is leaving the method without a result.
The type void is a type with zero values, so for void methods there is no x such that return x makes sense.
All non-void methods must do one of three things:
Fail to exit ever.
Finish abnormally with an exception.
Finish normally with zero or one return values.
Since void is the only type with zero possible values (Classes with private uncalled ctors don't count because of null), there is no possible return in a non-void method such that return makes sense.

Refresh Java argument

I am writing a program for a programming game called robocode. The problem is here:
void wallScan(boolean While){
stop();
getStraight();
turnGunRight(90);
if(startabsolute){
straight=true;
}
while (While){
ahead(10000000);
turnRight(90);
}
resume();
}
You might not understand most of the code as it extends robocode.Robot, but my problem is in the variable While. The loop doesn't end as the method gets the argument once and it is true so the method becomes an eternal loop but is there a way to refresh the method argument as I don't want to make a while loop every time I call this method?
You shouldn't write you parameters in capital letters. So it would be while instead of While. However this isn't allowed because while is a keyword. So first change your argument passed in the method.
Then your problem is, that you call the method with the argument. Since it is a primitive boolean value you pass, the value can't be changed from another method, call, class, etc. during the execution of your wallScan method and therefore the while loop never finishes.
Instead you should for example create a member field in the class containing this method an give it a meaningful way. in the example i just call it whileCondition.
void wallScan(){
stop();
getStraight();
turnGunRight(90);
if(startabsolute){
straight=true;
}
while (whileCondition()){
ahead(10000000);
turnRight(90);
}
resume();
}
public void setWhileCondition(boolean bool) {
whileCondition = bool;
}
public boolean isWhileCondition() {
return whileCondition;
}
So you can set the condition which leads to the termination of the while loop from outside your method.
It seems to me that you don't want a single boolean value - you want something which will return you a boolean every time you ask for one. As a simple example:
public interface ContinueChecker {
boolean shouldContinue();
}
(Horrible names, but hopefully you can come up with something better.) You can then write:
void wallScan(ContinueChecker checker) {
...
while (checker.shouldContinue()) {
...
}
}
An alternative form of this would be a generic interface, such as Provider<T> one from Guice:
public interface Provider<T> {
T get();
}
Your method could take a Provider<Boolean> for the same purpose.
Personally I prefer this approach over that of Sebi - it allows your class to represent the state of the board itself (or whatever) - whether one particular robot should stop doesn't feel like it should be part of the same state. It's effectively local to this method, as far as I can see.

Categories