I have a java program and want to generate javadoc for classes/interfaces. However, I just want to generate javadoc for a certain classes and interfaces. I just want to know if there is any way that I can add an annotation at the beginning of each class/interface to indicate that this class/interface should not be generated javadoc (something like #no-generate-javadoc)
Does anyone have ideas, please?
Thanks
Writing your own doclet is realtively straightforward and will give you exactly what you want. You can still delegate to the standard doclet, so your implementation only needs to include your specific changes.
The ExcludeDoclet would be a good starting point. It reads excluded classes from a file. You get excludes by annotation by calling the annotations() method on ClassDoc (actually it's base class, ProgramElementDoc) to fetch the annotations, and then check these against your desired exclude annotations. If desired, you could also do this recursively for superclasses and implemented interfaces,
Thanks for mentioning our tool - DocFlex/Javadoc
By the way, simply excluding classes and members isn't the whole story. The generated JavaDoc must look consistent after that.
For instance, suppose we have the following situation:
class C1 extends class C2
class C2 extends class C3
class C3 contains a public method m() -- which is supposed to be documented
Now, let's assume that the class C3 must be excluded from the documentation.
What will happen with the method m() ?
It should be shown in the documentation as declared in the class C2!
Then, for the class C1, m() must appear as inherited from the class C2
(rather than from the class C3, as it actually is in the code).
The same situation is with fields, which is actually even more complicated, because equally named fields not overload but shadow each other. For example
class C1 extends class C2
class C2 implements interface I
class C2 contains a private field F
interface I contains a public field F -- which might be documented
Let's assume the interface I must be excluded from the documentation.
What to do with the field I.F?
Actually, nothing! It shouldn't get in the documentation because it is shadowed by C2.F, which is private and, therefore, must be invisible.
Does simple tweaking (delegating) of the Standard Doclet solves such problems?
Our tool does!
Related
So if I write the following code in Java:
public class A extends A{
public static void main(String[] args){
}
}
This gives a compiler error message cyclic inheritance involving A.
The same happens if I write two classes A and B and A inherits B and B inherits A.
This makes sense to me, as it is quite hard to imagine how this would be possible anyway.
I then asked about this from one of the professors at my uni. He said there are languages where this is possible and he lamented how this is not possible in Java and that he had done some projects where he had used cyclic inheritance and so on, but I couldn't really understand any of it. He also mentioned he had had problems where he would have liked to use cyclic inheritance.
Can you educate me on the possible uses of this strange phenomena of cyclic inheritance? When is it possible and how? Are there problems where this could be useful?
I dug up this interesting reference: basically it says that cyclic inheritance is valid as long as there are no repeated fields, as the lookup for any field just needs to traverse one loop of the cycle to find out a meaning. If a field is repeated then none of the two definitions is more valid than the other and apparently there would be a problem.
So suppose that you want to define a person as a human and as a voter, and set different attributes for each. In pseudo-code:
class Person extends Human:
String name;
class Human extends Voter:
String language;
class Voter extends Person:
Country residence;
Now you can address different aspects of an individual without having to define a hierarchy, and you might instantiate different people as a Person (with name), a Human (that speaks a language) or a Voter (in a particular country). No aspect is more important than the other.
While interesting, I don't think it is practical to use outside of research projects. Imagine having constructors for all classes that pass parameters to the super() constructors -- it would be easy to mess up the whole construct.
Update: the given pseudocode does not compile when translated to Java 8, and apparently under any language (except Cecil as shown by the link given above). It seems that nobody found any valid uses and therefore disallowed cyclic inheritance. This does not mean that the concept is inherently impossible; just that the practical uses do not justify the effort implementing the special case.
I could only see it possible if the classes were on the same level of hierarchy. Think of the class hierarchy as a tree, which it is. Java looks for the hierarchy to be at least one level above or more. In some languages, you would be able to inherit characteristics from a class on the same level as the class you are using.
I don't get the sense of cyclic inheritance. I don't know why your professor thinks it's useful in anycase mind that the inheritance reation that is called IS-A relationship states that if B is a subclass of A then B IS-A A in the sense that everywhere an A is required then a B can be used without problem (Liskov substitution principle).
Now, theoretically, if A is a subclass of B and B is a subclass of A then then both classes must have exactly the same outside interface. This because if you add a method to any of them the other one will inherit the same method automatically so you will have either to override it either to get the other implementation.
In addition you will have many circumstanced in which odd side effects comes into play (think about method A.foo() calling super.foo() and B.foo() calling super.foo(). I don't see any practical reason because this should be allowed.
Inheritance is intended as a tree in which every subclass specifies the behavior or the classes that are up in the tree, having two classes at the same level doesn't mean anything useful.
I disagree with the accepted answer that states that their code will not throw an error. I am running Java 8 and compiled the following code:
class Person extends Human:
String name;
class Human extends Voter:
String language;
class Voter extends Person:
String residence;
and I recieved an error stating "error: cyclic inheritance involving Person."
Therefore, in Java you can not have cyclic inheritance.
Cyclic inheritance is of no use and moreover let us see why logically it is not allowed.
I would like to start with Object class, if a class doesn't extend any class it extends Object class (this is true), and if a class extends any other class indirectly extends the Object class.
Example:
class B
{
..//
}
class A extends B
{
...//
}
class A extends Object, because B class extends Object class.
So when we do Cyclic Inheritance, it never extended the Object class.
Example:
class A extends A
{
}
I hope I was clear, so and a class that cannot extend Object class that is not possible in Java.
I have made a program that consist of a few classes a class that extends however one class doesn't produce any JavaDoc or appear in the program tree. It is declared like this:
class myClass extends anotherClassOfMine {
}
Is there something special I need to add to anotherClassOfMine to ensure that the JavaDoc is created for myClass?
TIA
As mentiones in the comments, by default Javadoc only includes public and protected elements. Your class not being public, Javadoc thinks it is not intended to be documented.
You can either make your class public (adding public), or change Javadoc's behaviour by adding one of the access options -package or -private. Other values are -public or -protected (the default).
(Of course, you should also add some actual documentation, but one of the changes above should be enough so your class will show up.)
I have abstract methods in a class that need to be implemented by a foreign class in a SEPARATE project that uses my project.
-- All classes instanceof A are initially generated using reflection --
So anyway, say Class A is abstract, and Class B (non-abstract) extends A
B has all the unimplemented methods in Class A because B is in my workspace so I know to add those methods.
C also extends A, but C only has a subset of the abstract methods in A. C, however, is not in my workspace.
Therefore, for each abstract method in C NOT in A, I need to find some way to add the method for A like so:
(For each method)
public <corresponding return type> <missingMethodName>() { return null; }
Is this possible?
P.S. Please assume that I either have to completely rewrite my code to be in sync with the objects I have no control over, or implement a solution like the one I am alluding to above.
No, unless I'm reading you incorrectly, what you're asking for doesn't really make much sense.
If you wanted to inject a method
public <corresponding return type> <missingMethodName>() { super.<missingMethodName>(); }
into C, which extends A, which doesn't implement that method, what would it exactly do?
If you want to provide a default implementation in A, that's fine, and it won't affect C. If you add abstract methods into A, C must implement them, mark itself as abstract, or it won't compile (or throw serialization, or some weird error) if you run with a C compiled with an older A.
You should never need to do this as any instance method which has a super implementation can be called on a sub-class instance.
You can add these methods using byte code, but the only difference they would make is to change the list of getDefinedMethods(). However it wouldn't change the behaviour of the objects of the class.
its quiet difficult but you can do it with Javassist
Javassist (Java programming assistant) is a Java library providing a means to manipulate the Java bytecode of an application.1 In this sense Javassist provides the support for structural reflection, i.e. the ability to change the implementation of a class at run time.
Bytecode manipulation is performed at load-time through a provided class loader.
http://en.wikipedia.org/wiki/Javassist
Here's something that's got me a bit stumped but intrigued all the same. In my Android game I have various Levels that extend the superclass Level. What I am trying to do is build a levelDirectory (based on the Singleton DP) that essentially is an object that has a HashMap object within it that stores all the Level subclasses. Here is my question:
We're all familiar with the enhanced for loop, but how can I write something that would be the equivalent of
for(Level l : An Array Of Every Level Subclass In My Project that is an Extension of the Level Superclass){
HashMap.put(l.name, l);
}
I am trying to build a system that can dynamically update itself when I add more and more level subclasses. I know having a method in Level that submitted itself to the static Directory and was called in the Level's constructor is an option, But I'm just wondering whether there is a way of doing what I said above in that enhanced for loop?
Many thanks
The question itself is wrong. You cannot loop over List ("Every Level Subclass In My Project") and get instances of Level. l should be Class.
From the context, I think you meant "every instance of every Level subclass". No, it is not possible - a virtual machine is not and should not be a database. You cannot just query for objects, you have to manage references in your code (but that you already knew that - your constructor solution will work).
Option 1:
Lately I had to solve a similar problem within JavaSE. I'm using the Google Reflections Library for that:
http://code.google.com/p/reflections/
However I'm not sure if it can run with Android. I think it's worth to give it a try, since it's quite easy to use. In your case you would do something like:
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends Level>> subTypes = reflections.getSubTypesOf(Level.class);
That would give you a Set (subTypes) to iterate on and put it in the HashMap.
Option 2:
You could maybe use custom annotations to annotate your Level classes, for example:
#Level public class MyCustomLevel {}
Then use a custom annotation processor which implements AbstractProcessor to process the annotation at compile time. Implement the process method to find all classes annotated with your #Level annotation. Now you can write the full names of the found classes to a property file in your META-INF dir. From your application you can read this property file and instantiate the classes using reflection.
If you're trying to dynamically fetch the list of all classes that extend Level at runtime, that's not really possible, I'm afraid. Have a look at this thread: How do you find all subclasses of a given class in Java?
I think you might want to make the level an interface and then check if it's an interface.
In its most common form, an interface is a group of related methods with empty bodies. A bicycle's behavior, if specified as an interface, might appear as follows:
interface Bicycle {
void changeCadence(int newValue); // wheel revolutions per minute
void changeGear(int newValue);
void speedUp(int increment);
void applyBrakes(int decrement);
}
To implement this interface, the name of your class would change (to a particular brand of bicycle, for example, such as ACMEBicycle), and you'd use the implements keyword in the class declaration:
class ACMEBicycle implements Bicycle {
// remainder of this class implemented as before
}
Implementing an interface allows a class to become more formal about the behavior it promises to provide. Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler. If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile.
I think standard way in the "spirit" of java is the service provider pattern.
Add a declaration file in the META-INF/services of the "plugin" jar and use java.util.ServiceLoader (http://developer.android.com/reference/java/util/ServiceLoader.html) to enumerate your providers.
Don't know much about Android but sounds like Reflection might help here, so what do you know about reflection in Java?
EDIT
Didn't know you had to limit yourself to loaded levels. That being the case you would want to do your tracking on every instance as it is created pretty much like you proposed in your question.
My idea involved parsing all the directories of a project looking for subclasses - it could be done once at the start of program execution but it would list levels that may never get instantiated...
I need to do some refactoring in Java, and I need to maintain some degree of binary compatibility. In this case I want to remove some legacy interfaces, that are not used anywhere anymore and which require a rather big (and also deprecated) external dependency.
I have class C that implements interface I, and I have code that calls a method (declared in the interface) on an instance of C. The calling code knows that it is using C, not just the interface.
class C implements I {
void theMethod(){} ; // is declared in the interface I
}
C object;
object.theMethod();
When I remove the interface from the class definition (but keep all the methods), will the calling code (which does not refer to the interface at all) still work (without a recompile)?
Yes, it will work - as long as it doesn't explicitly refer to interface I anywhere.
From JLS: Resolution of Symbolic References:
The binary representation of a class
or interface references other classes
and interfaces and their fields,
methods, and constructors
symbolically, using the binary names
(ยง13.1) of the other classes and
interfaces
Class ClientClass referring to field / method of class C contains no implicit references to interface I that class may implement.
It works as long as an object of class C is never referred to as I.
You can also refer to Evolving Java-based APIs part 2.
You might have a problem with the calling Code if it imports the Interface anywhere. If there is no import of the interface in any of the calling code, you can be reasonably confident that your refactoring will work as planned.