I'm working on a internship project, but I have to leave before I can finish up everything.

I have 1 class that is not stable enough for production use. I want to mark/flag this class so that other people will not accidentally use it in production. I have already put the notice in Javadoc, but that doesn't seem enough. Some compiler error or warning would be better.

The code is organized like this:

[Package] | company.foo.bar.myproject
          |-- Class1.java
          |-- Class2.java
          |-- Class3.java <--(not stable)

If there was a single factory class that calls those classes in public methods, I could have set the method to class3 as private. However the API is NOT exposed that way. Users will directly use those class, e.g. new Class1();, but I can't make a top-level class private. What's the best practice to deal with this situation?

  • 1
    What do you mean by "The API is not exposed through methods?" Is this class intended to be used via the Reflection API? – Tom G Aug 10 '11 at 16:26
  • 5
    A compiler error? Why not just throw an exception in constructor? – Mchl Aug 10 '11 at 16:32
  • Sorry for the confusion. I have edited my post. – Wei Shi Aug 10 '11 at 16:33
  • 1
    You can't make the class private, but you can make its constructor private. – Peter Taylor Aug 11 '11 at 12:15

10 Answers 10


Why not just check all the unstable classes into a different branch on your version control system?

  • 2
    Seems to me that this would 'hide' the code. What if the code almost does what others need it to do with some minor tweaks. If you put it in a branch they might never see it and would just re-implement the whole thing. – c_maker Aug 10 '11 at 17:21
  • 3
    @c_maker: Letting others know the branch exists and what's in it should be a part of what gets passed on when he leaves. – Blrfl Aug 10 '11 at 17:52
  • 2
    @Birlf If he is worried about others not seeing the explanation in the JavaDoc of code that they are using, I doubt that they will go looking for the other documentation that he produces. – KeithB Aug 10 '11 at 21:21
  • My concern is that the feature is still evolving, but the scrum master chose to set it aside for any reason (moratorium that blocks E2E testing, in our case). If we don't join it to master, there may be a lot of merge work down the road. We just made the c`tor private, and annotated the class @Experimental, like in Spark – Joey Baruch Nov 22 '18 at 7:33

If you have properly commented the class you could mark the bits of incomplete functionality as "deprecated" and or comment out the guts of the method and put a throw new UnsupportedOperationException();.

See Is there anything like .NET's NotImplementedException in Java? for details.

  • 2
    This is the defacto way of dealing wit hit as I understand things – Martijn Verburg Aug 10 '11 at 17:25

I do not know such compiler warning.

In your situation I would probably use the @Deprecated annotation. It will cross out method calls so it will be obvious to the others that something is up. When they look at whats up, they will see your comments about 'not production ready' and go AHA.

  • 2
    method calls only get crossed out if the IDE supports it. – FrustratedWithFormsDesigner Aug 10 '11 at 16:52
  • 5
    True, but most people will probably use one of those IDEs that supports it. – c_maker Aug 10 '11 at 16:55

Why is it there in the first place?

You've checked unstable code into the mainline? Why?

Unstable code shouldn't be checked into trunk / main / master or whatever the main trunk name is. This is considered to be high risk development and should instead have been sequestered off in its own branch that you worked on rather than checked into main.

I would strongly encourage you (and your team lead) to read Advanced SCM Branching Strategies. In particular, pay attention to the development role and what it says about what is considered to be high risk development:

In general, consider using separate branches for each high-risk project. High risk projects are characterized by large size, large numbers of people, unfamiliar subject matter, highly technical subject matter, very tight time lines, uncertain delivery dates, incomplete or volatile requirements, and geographically distributed project teams. Similarly, consider designating a single branch for low risk development in each release. Several sources including [WING98] recommend using the mainline for this purpose. Consider the factors discussed above for the mainline before committing to this course of action. Low risk development may have different policy from the mainline even if you have multiple members of a product family coordinating through the mainline.

Letting people check unstable (or unused) code into mainline means that you will confuse future development efforts about trying to maintain this code. Every branch and clone of the rep from now until the end of time will contain this until someone says "its dead codE" and deletes it.

There are some that say "well, if its in a branch it gets forgotten" and while that may be true, having forgotten dead (and unstable) code in mainline is many times worse as it confuses all future development until it is removed - and then it is even more forgotten. A nicely named branch of "/fooProject/branches/WeisBigIdea" (or equivalent) is visible and easier to work with in the future - especially if it kind of works.


The first thing is the @Deprecated annotation. This goes beyond the javadoc and spits out compiler warnings. javac provides a -deprecation flag that is described as:

Show a description of each use or override of a deprecated member or class. Without -deprecation, javac shows a summary of the source files that use or override deprecated members or classes. -deprecation is shorthand for -Xlint:deprecation.

As noted, this goes above and beyond the standard compiler warnings.

In many IDEs, deprecated methods and values are shown with a strikethrough:


And would produce output like:

$ javac -Xlint:all Foo.java Bar.java
Bar.java:2: warning: [deprecation] Foo in unnamed package has been deprecated
interface Bar extends Foo { }

Depending on your build structure, you may have warnings break the build. This would only break the build if one of your classes was used (not if it is just simply compiled in).


There are many approaches to this. For example, the Lightweight javac @Warning annotation which provides an annotation processor that fires off a warning at compile time when something with that annotation is used (a netbeans tutorial on custom annotation processors so you can get an idea of what is going on behind the scenes).

Oracle even describes an example of using custom annotations for an @Unfinished annotation in Making the Most of Java's Metadata, Part 2: Custom Annotations.

With the AnnotationProcessor, you can run arbitrary code at compile time. Its really up to you to decide what you want it to do. Warn, break the build when something is used. There are numerous tutorials out there on the web for how to write this sort of code. Whether you want to generate an error when its compiled (this will be annoying and lead to it getting deleted) or if its used (quite a bit more complex to write).

Note that all of this implies changing the builds to actually use the annotation processor.


I don't think there is a standard way of marking code as WIP, Incomplete, or something like that.

You could create a new exception named ClassUnstableException and then raise it in the Class3 constructor with a message that explains how they shouldn't use it. This is bad though, because it only warns them at run time.

You could also try making the class incompilable in some way, and then add a note to the section of code that trips the compiler so that if someone goes to fix the code they will hopefully see an explanation of why they shouldn't use that class. This may not work if they use some semi-automated "fix this problem" tool that some IDEs have. This is also bad because it could break builds.

You could create an annotation named WIP (since the closest I can think of is Deprecated but it doesn't really mean the same thing) and use it to annotate the class. This would probably be a bit more work, and what would support the annotation?

Finally, you could just put it in the comments, but that will only work if people actually read them.


This may be relevant: How to intentionally cause a custom java compiler warning message?

  • throw exception makes the eclipse complain about unreachable code. Any workaround? – Wei Shi Aug 10 '11 at 17:01
  • @Usavich: Not sure since I haven't seen the code, but maybe that could also help prevent future developers from using the code? – FrustratedWithFormsDesigner Aug 10 '11 at 17:04
  • @Usavich: Have a look at the link I added in the EDIT in my post, it's a similar question where the OP wanted to add a custom compiler warning. Might help you add a custom "UnstableCode" annotation. – FrustratedWithFormsDesigner Aug 10 '11 at 20:19

You could introduce compile time annotation processing but this would enforce all members of the team to adjust their compile process.

However I find the whole process a little confusing. An unstable API should be clearly separated by creating a branch in your version control system. If it really has to be in the rest of the codebase, has been documented as unstable and nevertheless get's used the problem is not really technical but lies within the organisation and the communication. Yes, you could introduce technical verifications (like annotation processing) but that wouldn't solve the problem - just move it to another level.

So my recommendation is: If you cannot separate the code base by putting it in different branches then talk to people and explain to them why they mustn't use the API.


Could you move all the incomplete classes into a subpackage named something obvious like "NOTCOMPLETE"? It's a bit of a hack but might be visible enough.

(If they are not all in the same package, you could recreate the package structure under there.)


I don't know that there is really a good way to do this in the code. Take a step back:

Create two copies of the whole project, one with the class, and one without. Mark the version without the class as a stable codebase, ready for production release, and the version with the class as development for a future release. Document what needs to happen before this class can be considered production-quality.

Ideally, you should do this using branches in your source control solution of choice. You might have to cheat a bit though, since it sounds like you haven't been using such a branching strategy. Carefully remove the new class, check in a version without it, and do some regression testing. When you're satisfied it's stable, you can tag that revision, create a development branch from the tag, and then add the class back in the development branch.


I'd opt for making the class abstract, and commenting appropriately - that way, the code is still there for reference, but good luck to anyone who tries to instantiate it :)


What about making a dependency that the compiler can't resolve? Just add:

import this.is.not.done.yet.do.not.use.it;

to the top. Users won't be able to compile with it.

If you want to test out the class, simply create a package/class with that name (or use a simpler one like "experimental.danger") and you can test the new code.

  • 1
    The compile will fail even if I don't use it ... bad idea ... – Silviu Burcea May 13 '14 at 11:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.