1

I am writing a method that is a little overpowered and I want to throw a warning to my user telling him to "better know what you're doing", just like the way @deprecated behaves. I can write this one the method name, but I wonder if there is a more elegant way of doing this.

public class Divison {

public Divison() {
}

private int up;
private int down;


public int eval() {
    return ((int) up/down);
}

public void setVars(int up, int down) {
    this.up = up;
    if (up%down == 0) {
        this.down = down;
    } else {
        throw new ArithmeticException("the values must be divisible");
    } 
}

public void betterKnowWhatYouDoingSetVars(int up, int down) {
    this.up = up;
    this.down = down;
}

}

  • 1
    `@Deprecated` or warning in bold in the javadoc should be enough – davidxxx Jul 04 '19 at 21:26
  • A quick perusal of Javadoc tag list does not show anything. https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDFJAFC – Compass Jul 04 '19 at 21:27
  • You mean, `@no_encapsulation`? No, there's nothing like that. :) – Costi Ciudatu Jul 04 '19 at 21:31
  • I would just solve it by calling it `setVarsUnsafe(int up, int down)` Function name tells you it is unsafe. Should be a warning by itself right? – Software Person Jul 04 '19 at 21:34
  • 2
    Is this your actual class, or just an example? Honestly, if you feel you have to warn people about sharp edges on your API, you should perhaps revisit the design of the API. (I'd be much more concerned about the lack of failure atomicity in `setVars` than the fact you could end up with non-divisible fields). – Andy Turner Jul 04 '19 at 21:39
  • @AndyTurner it is just an example. – Matheus Popst de Campos Jul 04 '19 at 21:46
  • @SoftwarePerson I am solving the way you told. – Matheus Popst de Campos Jul 04 '19 at 21:47
  • Annotation preprocessing might help with this, but also seems like overkill - https://stackoverflow.com/questions/34519957/make-the-java-compiler-warn-when-an-annotated-method-is-used-like-deprecated – broot02 Jul 04 '19 at 22:20

1 Answers1

1

Allowing the outer world to break your invariants is never a good idea, as your class becomes useless: since I can't rely on its internal state being consistent, it's just a bag of values unrelated to each other. To write correct programs, I would need to replicate all your validation logic inline before every usage of that class.

By the way, your example implementation can get in an inconsistent state even without the betterKnowWhatYoureDoing... method, and I'm not even mentioning multi-threading. You can prevent that by simply making the class immutable and doing that check in the constructor.

I think you should thoroughly re-evaluate your design before going this route.

If you must provide such functionality (I can hardly imagine any reason why), at least make it package-private (instead of public and documented as "dangerous").

Also, those who really know what they're doing are probably never going to call that method anyway, so it's a bit pointless... :)

Costi Ciudatu
  • 37,042
  • 7
  • 56
  • 92