How to hide a public method? - java

I have a method in my static state machine that is only used once when my application is first fired up. The method needs to be public, but I still want it hidden. Is there a way to use an annotation or something that will hide the method from the rest of the project?

You cannot make a public method hidden (unless you can declare it private). You can however put in a subclass and only let the users of the object know the type of the superclass, that is:
class A {
//Externally visible members
}
class B extends A {
//Secret public members
}
Then you instantiate the class B, but only let the type A be known to others...

Once you declare public method it becomes part of your class's contract. You can't hide it because all class users will expect this method to be available.

You could use package level instead of public. That way it can only be called by your application.

If a method is public, it can't be hidden. What you may really be looking for is just a way to restrict access to calling a method. There are other ways to achieve a similar effect.
If there are some things that your state machine does that are "only used once when my application is first fired up" it sounds a lot like those are things that could happen in the constructor. Although it depends on how complex those tasks are, you may not want to do that at construction time.
Since you said your state machine is static, is it also a Singleton? You could maybe use the Singleton Pattern.
public class SimpleStateMachine {
private static SimpleStateMachine instance = new SimpleStateMachine();
private SimpleStateMachine() {
super();
System.out.println("Welcome to the machine"); // prints 1st
}
public static SimpleStateMachine getInstance() {
return instance;
}
public void doUsefulThings() {
System.out.println("Doing useful things"); // prints 3rd
}
}
Here's some code for a client of this Singleton:
public class MachineCaller {
static SimpleStateMachine machine = SimpleStateMachine.getInstance();
public static void main(String... args) {
System.out.println("Start at the very beginning"); // prints 2nd
machine.doUsefulThings();
}
}
Note that the SimpleStateMachine instance isn't built until the first time your class is accessed. Because it's declared as static in the MachineCaller client, that counts as a "first access" and creates the instance. Keep this tidbit in mind if you definitely want your state machine to perform some of those initialization tasks at the time your application starts up.
So, if you don't want to turn your state machine class into a true singleton... you can use a static initialization block do your one-time tasks the first time the class is accessed. That would look something like this:
public class SimpleStateMachine {
static {
System.out.println("First time tasks #1");
System.out.println("First time tasks #2");
}
public SimpleStateMachine() {
super();
System.out.println("Welcome to the machine");
}
public void doUsefulThings() {
System.out.println("Doing useful things");
}
}
While we're at it, since you mentioned that it's a state machine... the Head First Design Patterns book does a nice, easily understandable treatment of the State Pattern. I recommend reading it if you haven't already.

The idiomatic approach to doing this is to use interfaces to limit the visibility of your methods.
For example, say you have the following class:
public class MyClass {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
If you want to limit some parts of the project to only see method1(), then what you do is describe it in an interface, and have the class implement that interface:
public interface Method1Interface {
public void method1();
}
...
public class MyClass implements Method1Interface {
public void method1() {
// ...
}
public void method2() {
// ...
}
}
Then, you can limit the visibility of the methods by choosing to pass the class around either as a MyClass reference, or as a Method1Interface reference:
public class OtherClass {
public void otherMethod1(MyClass obj) {
// can access both obj.method1() and obj.method2()
}
public void otherMethod2(Method1Interface obj) {
// can only access obj.method1(), obj.method2() is hidden.
}
}
A bonus of this approach is that it can also be easily extended. Say, for example, you now also want to independently control access to method2(). All you need do is create a new Method2Interface along the same lines as Method1Interface, and have MyClass implement it. Then, you can control access to method2() in exactly the same manner as method1().
This is a similar approach to that advocated in #MathiasSchwarz's answer, but is much more flexible:
The independent access control described in the preceding paragraph isn't possible with Mathias' technique, due to Java not supporting multiple inheritance.
Not requiring an inheritance relationship also allows more flexibility in designing the class hierarchy.
The only change required to the original class is to add implements Method1Interface, which means that it is a very low-impact refactor since existing users of MyClass don't have to be changed at all (at least, until the choice is made to change them to use Method1Interface).

An alternative solution: You can make it private and create a invokeHiddenMethod(String methodName, Object ... args) method using reflection.

You said that your public method is used only once when the application is started up.
Perhaps you could leave the method public, but make it do nothing after the first call?

There is a (non-)keyword level package level visibility. Instead of public, protected, or private, you use nothing.
This would make the method or class visible to the class and others in the package, but would give you a certain modicum of privacy. You may want to look at What is the use of package level protection in java?.

Hmm... You want a private method, but want to access it outside?
Try do this with reflection.
http://download.oracle.com/javase/tutorial/reflect/index.html

I have seen many Java programmers do something like this:
public static void main(String args[]) {
new MyClass();
}
So basically they create just one object of the class. If there is a method which should run only once, I guess this approach can achieve that. Your method will be called from inside the constructor. But since I don't know how your app works, what are the constraints, so it is just a thought.

Related

Why is subclass field initialized to its default value within super constructor? [duplicate]

I ran into an interesting problem yesterday and while the fix was quite simple, I'm still a bit fuzzy on the "why" of it.
I have a class that has a private member variable that is assigned when it is instantiated, however if it is used in an abstract function that is called by the super class's constructor, the variable does not have a value. The solution to the problem was quite simple, I simply had to declare the variable as static and it was assigned correctly. Some code to illustrate the problem:
class Foo extends BaseClass
{
private final String bar = "fooBar!";
public Foo()
{
super();
}
#Override
public void initialize()
{
System.out.println(bar);
}
}
And the base class:
abstract class BaseClass
{
public BaseClass()
{
initialize();
}
public abstract void initialize();
}
In this example, when we call new Foo(); it will output (null) instead of the expected fooBar!
Since we're instantiated an object of type Foo, should its members not be allocated and assigned prior to calling its (and consequently its super class's) constructor? Is this specified somewhere in the Java language or is it JVM specific?
Thanks for any insight!
The assignment of bar = "fooBar!"; is inlined into the constructor during compile time.
The superclass constructor runs before the subclass constructor, hence it would only be natural that the statement is executed afterwards.
Generally though, it's bad practice to call overridable methods from a constructor.
It is as defined by the Java Language Specification. Changing it to static will almost never be and acceptable solution in real world situation.
See JLS 4.12.5 Initial Values of Variablesand JLS 8.3.2 Initialization of Fields
Overall, it is bad practice to call a non-final method from a constructor. the reason being that it could (and if the method is abstract then definitely does) call method in the class that has not yet been initialized: When new Foo() is executed, the BaseClass initializer (constructor) gets called before the Foo constructor, so Foo.initialize is essentially working on an Object that has not been fully constructed yet.
There's just one thing I would like to add to the accepted answer, because I don't entirely agree with his conclusion.
We've all done this.
class Engine {
public Engine() {
init();
}
void init() {
lockDoors();
releasePressure();
tightenSeatbelts();
launchRocket();
}
...
}
Now the question is, which access modifier should we add to our init() function. Should it be private or protected.
make it private <-- keeps subclasses out
make it protected <-- allows subclasses in
Before you make a choice
Now first of all, you should realize that (almost) all code in the Engine class can be replaced by a subclass.
code in a public function, can easily be overridden
code in a protected function, can easily be overridden
code in a private function, can be replaced by overriding all methods that call it.
Well, there is just one exception:
you can never modify the code of a constructor
you can never avoid a private method being called from the constructor of a super class.
(and of course, you cannot replace a final method)
Protected init() - the wrong way
Let's say the init() method is protected there is indeed a pitfall. It is tempting to override it to add features as follows. That would indeed be a mistake.
class SubEngine extends Engine {
int screws = 5;
void init() {
tightenScrews();
super.init();
}
void tightenScrews() {
// this won't print 5, but it will print 0.
System.out.println("tightening " + screws + " screws");
}
}
Protected init() - the right way
So, basically, you should just disable the parents code and postpone execution to your own constructor instead.
class SubEngine extends Engine {
int screws = 5;
public SubEngine() {
initSubEngine();
}
void init() {
// disable parent code
}
void initSubEngine() {
tightenScrews();
super.init();
}
void tightenScrews() {
// this will print 5 as expected
System.out.println("tightening " + screws + " screws");
}
}
Private init() - you may need a phonecall
Now, what if the init() method is private ?
Like mentioned above, there is no way to disable the code of a parent constructor. And if init() is private you simply cannot disable it.
You'll end up copying the entire Engine class, perhaps just to add 1 line of code.
And that may not be the end of it. Even after copying your class, your copied object won't be an Engine meaning that you won't be able to use your EngineUtil#inspectEngine(Engine engine) function.
Perhaps somebody knew this in advance and made an IEngine interface. Then you can get away with it.
In practice it means you'll have to take your phone, and call to that other department that made the Engine class, and ask them to change their code a little to take away some restrictions.
Intelligent design
There is another way. Constructors are for setting variables. They shouldn't activate anything. Everytime you see a class creating a new Thread from their constructor (or through a private method) that should be a red flag.
class Engine {
public Engine() {
}
public void init() {
lockDoors();
releasePressure();
tightenSeatbelts();
launchRocket();
}
// and you probably also want one of these
public void shutdown() { ... }
...
}
Intention
Of course, your intention may very well be not to open up your code. Perhaps you really don't want to allow others to extend your classes. There certainly can be cases where you want to lock people out.
Be aware that it will also make it harder to write tests for your code.
Anyway that's a different scenario.

How to prevent sublasses from default implementing a method of super class?

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.

How to have a public void method that must be run at least once

Suppose I have a class ClassA whose getters and setters I use multiple times in my program. Suppose at the end of the program it is critical that I run the public void checkErrors() within the instance of ClassA that I've been working with, which will throw an exception or log an error if there is an error.
Is there a way I can set up ClassA that will throw a RuntimeException if checkErrors() isn't called at least once by the main method?
For example, hoping that you have an imagination, it would be good to have a method like: public compulsory void checkErrors() where compulsory means it must be run once by the main method.
This is an event driven programming context.
In my problem, the instance of ClassA might be needed for a few calculations then not needed any more (with the state of the class, resulting from various internal calculations and setters, being used in other parts of the program). Thus, at the end of the instance's life in the program, I would like to checkErrors() before continuing the program (thus stopping error propagation to later stages of the program).
This compulsory thing would just be to stop the error on behalf of the programmer to call this method at least once.
I want make it compulsory for the main method to checkErrors() on ClassA before ClassB uses ClassA's state in an event driven programming case.
Then you shouldn't design the program this way. Instead, you should introduce a class ValidState and pass an instance of this class to ClassB. And ClassA should have a method
ValidState produceValidState() throws IllegalStateException
which would check for errors and, if none, produce the valid state.
That way, it's completely impossible for the main method to pass invalid state to ClassB. It has to ask ClassA to check for errors in order to get the valid state that ClassB needs to work.
What you are requesting goes against the principle of object oriented programming, as individual classes should encapsulate specific behaviour, without having to be concerned with the flow of the whole program. The class itself shouldn't be aware, that something was supposed to happen with it, it should have been instantiated, etc., this should be monitored outside of the class, in the main flow.
Therefore if you need to do this badly, you can add a counter to ClassA that counts, how many times something was performed and then check this counter in the main.
Sure what you are talking about is the validity of the data in your class. At some point the data is valid. So you need to check the validity of your data every time it is changed and maintain the state of this validity.
private boolean isValid;
public void setSomeData() {
// set it
checkIfErrors();
}
public Data getSomeData() {
if (isValid) {
return someData;
} else {
throw new DataIsInvalidException();
}
}
private void checkIfErrors() {
if (isOk) {
isValid = true;
}
}
There's no certain way to guarantee that an object's method is called after it's constructed. You can, however, require that a method be called before another method; this pattern can be used to enforce a "lifecycle", for example.
boolean errorChecked = false;
public void checkForErrors() {
// do stuff and throw exception if there's a problem
errorChecked = true;
}
public void doSomething() {
if(!errorChecked)
throw new IllegalStateException("must call checkForErrors() first");
...
}
While this paradigm is not really suited for the purposes you are seeking, you could try something like this.
Create a class Monitor:
public class Monitor{
private static ArrayList<Object> checkList;
public static void addToList(Object a){ // implementation }
public static void removeFromList(Object a){ // implementation }
}
This class could have a timer thread that checks its contents every so often. Then you can build right into the class you need checked:
public class ClassA{
public ClassA(){
Monitor.addToList(this);
...
}
public void checkErrors(){
Monitor.removeFromList(this);
...
}
}
So all the timer needs to do is look at the list every so often and see if any of the objects in it are null. If one is null, something was freed without a call to checkErrors(), and you can throw your exception.

Why are member objects initialized after the super class's constructor?

I ran into an interesting problem yesterday and while the fix was quite simple, I'm still a bit fuzzy on the "why" of it.
I have a class that has a private member variable that is assigned when it is instantiated, however if it is used in an abstract function that is called by the super class's constructor, the variable does not have a value. The solution to the problem was quite simple, I simply had to declare the variable as static and it was assigned correctly. Some code to illustrate the problem:
class Foo extends BaseClass
{
private final String bar = "fooBar!";
public Foo()
{
super();
}
#Override
public void initialize()
{
System.out.println(bar);
}
}
And the base class:
abstract class BaseClass
{
public BaseClass()
{
initialize();
}
public abstract void initialize();
}
In this example, when we call new Foo(); it will output (null) instead of the expected fooBar!
Since we're instantiated an object of type Foo, should its members not be allocated and assigned prior to calling its (and consequently its super class's) constructor? Is this specified somewhere in the Java language or is it JVM specific?
Thanks for any insight!
The assignment of bar = "fooBar!"; is inlined into the constructor during compile time.
The superclass constructor runs before the subclass constructor, hence it would only be natural that the statement is executed afterwards.
Generally though, it's bad practice to call overridable methods from a constructor.
It is as defined by the Java Language Specification. Changing it to static will almost never be and acceptable solution in real world situation.
See JLS 4.12.5 Initial Values of Variablesand JLS 8.3.2 Initialization of Fields
Overall, it is bad practice to call a non-final method from a constructor. the reason being that it could (and if the method is abstract then definitely does) call method in the class that has not yet been initialized: When new Foo() is executed, the BaseClass initializer (constructor) gets called before the Foo constructor, so Foo.initialize is essentially working on an Object that has not been fully constructed yet.
There's just one thing I would like to add to the accepted answer, because I don't entirely agree with his conclusion.
We've all done this.
class Engine {
public Engine() {
init();
}
void init() {
lockDoors();
releasePressure();
tightenSeatbelts();
launchRocket();
}
...
}
Now the question is, which access modifier should we add to our init() function. Should it be private or protected.
make it private <-- keeps subclasses out
make it protected <-- allows subclasses in
Before you make a choice
Now first of all, you should realize that (almost) all code in the Engine class can be replaced by a subclass.
code in a public function, can easily be overridden
code in a protected function, can easily be overridden
code in a private function, can be replaced by overriding all methods that call it.
Well, there is just one exception:
you can never modify the code of a constructor
you can never avoid a private method being called from the constructor of a super class.
(and of course, you cannot replace a final method)
Protected init() - the wrong way
Let's say the init() method is protected there is indeed a pitfall. It is tempting to override it to add features as follows. That would indeed be a mistake.
class SubEngine extends Engine {
int screws = 5;
void init() {
tightenScrews();
super.init();
}
void tightenScrews() {
// this won't print 5, but it will print 0.
System.out.println("tightening " + screws + " screws");
}
}
Protected init() - the right way
So, basically, you should just disable the parents code and postpone execution to your own constructor instead.
class SubEngine extends Engine {
int screws = 5;
public SubEngine() {
initSubEngine();
}
void init() {
// disable parent code
}
void initSubEngine() {
tightenScrews();
super.init();
}
void tightenScrews() {
// this will print 5 as expected
System.out.println("tightening " + screws + " screws");
}
}
Private init() - you may need a phonecall
Now, what if the init() method is private ?
Like mentioned above, there is no way to disable the code of a parent constructor. And if init() is private you simply cannot disable it.
You'll end up copying the entire Engine class, perhaps just to add 1 line of code.
And that may not be the end of it. Even after copying your class, your copied object won't be an Engine meaning that you won't be able to use your EngineUtil#inspectEngine(Engine engine) function.
Perhaps somebody knew this in advance and made an IEngine interface. Then you can get away with it.
In practice it means you'll have to take your phone, and call to that other department that made the Engine class, and ask them to change their code a little to take away some restrictions.
Intelligent design
There is another way. Constructors are for setting variables. They shouldn't activate anything. Everytime you see a class creating a new Thread from their constructor (or through a private method) that should be a red flag.
class Engine {
public Engine() {
}
public void init() {
lockDoors();
releasePressure();
tightenSeatbelts();
launchRocket();
}
// and you probably also want one of these
public void shutdown() { ... }
...
}
Intention
Of course, your intention may very well be not to open up your code. Perhaps you really don't want to allow others to extend your classes. There certainly can be cases where you want to lock people out.
Be aware that it will also make it harder to write tests for your code.
Anyway that's a different scenario.

Java - Restricting by what a method can be called

I have methods set to public because they must be called by an exterior class, but I only ever want them called by one or two methods. Being called by other methods could create bugs in my program. So, in order to prevent me from accidentally programming around my own methods, I have been doing stuff like this within the methods of which I want to restrict callers:
if(trace.length<2){
throw new Exception("Class should not call its own function.");
}else if(trace[1].getClassName()!=desiredClassName || trace[1].getMethodName()!=desiredMethodName){
throw new Exception(trace[1].getClassName()+"\" is invalid function caller. Should only be called by "+desiredClassName+"->"+desiredMethodName+".");
}
Is there something else I should be doing, or should I just not forget how my program works?
You should be using visibility to restrict calling - making a method public (or for that matter, javadocing it) is not going to work unless you have dicipline (and you control the callers too). From your description, you are neither.
What you can do is make the class package private, and put it in the same package as the two callers of that class. As long as you have a proper package structure, this can work. E.g.:
Your class that should only be called by A and B:
package thepackage.of.a.and.b;
//imports here
class CallableByAB {
public void methodA(){}
public void methodB(){}
}
A:
package thepackage.of.a.and.b;
public class A {
/*...other code here */
new CallableByAB().methodA();
/*...other code here */
}
B:
package thepackage.of.a.and.b;
public class B {
/*...other code here */
new CallableByAB().methodB();
/*...other code here */
}
other classes cannot call new CallableByAB() or import it. hence, safety.
This seems like a very brittle solution to a problem you should not need to solve.
In this particular case you may not suffer too greatly in future maintenance, just a couple of methods with these kind of special guards. But imagine trying to apply such logic to many methods across a large code base - it's just not a tenable thing to do. Even in your case you are effectivley writing code that cannot be reused in other contexts.
The fact that you need to do this surely reflects some kind of mis-design.
I infer that you have some kind of stateful interface whose state gets fouled up if called unexpectedly. Ideally I would want to make the interface more robust, but if that just cannot be done: If there are particular methods that should use this interface can you move those methods to a specific class - maybe an inner class of the current objtec you have - and have a handle visible only in this class?
private Class TheLegalCaller {
private RestrictedCallee myCallee = new RestricatedCallee() ; // or other creation
public void doOneThing() { myCallee.doOne(); }
public void doOtherThing() } myCallee.doOther(); }
}
Now the downside with this is that it only pushes the problem up a level, if you randomly use TheLegalCaller in the wrong places then I guess you still have an issue. But maybe by making the restriction very visible it aids your memory?
Try using access rules.
http://groups.google.com/group/google-web-toolkit/browse_thread/thread/90c424dc44db523e
I found a very simple way to do that, but requires some coding methodology:
class AllowedCaller {
private Object key;
public boolean getKey(){
return key;
}
public void allowedCallingMethod(RestrictedAccessClass rac){
this.key = rac;
rac.restrictedMethod();
this.key = null;
}
}
class RestrictedAccessClass{
public void restrictedMethod(){
if(allowedCallerInstance.getKey() != this){
throw new NullPointerException("forbidden!");
}
// do restricted stuff
}
}
I think it could be improved to prevent multithread simultaneous access to restrictedMethod().
Also, the key could be on another class other than AllowedCaller (so RestrictedAccessClass would not need to know about AllowedClass), and such control could be centralized, so instead of a single key, it could be an ArrayList with several object keys allowed at the same time.

Categories