Доклет - Получить дженерики списка - PullRequest
7 голосов
/ 20 апреля 2011

Я пишу доклет, расширяющий com.sun.javadoc.Doclet.

Когда я хочу документировать ArrayList как поле метода, я хочу получить тип универсального (например, при документированииArrayList<String> Я хочу получить информацию, что это список, содержащий строки).

Я могу получить только информацию, что это ArrayList.Даже при вызове

ParameterizedType paramType = fieldType.asParameterizedType();

я получаю только java.util.ArrayList , а не тип универсального.

Кто-то знает, как получить универсальный типсписка?

Вот пример кода:

FieldDoc[] fields = classDoc.fields();
for (int k = 0; k < fields.length; k++) {
    Type fieldType = fields[k].type();
    if (fieldType.asParameterizedType() != null) {
        ParameterizedType paramType = fieldType.asParameterizedType();
        String qualiName = paramType.qualifiedTypeName(); // this equals "java.util.ArrayList"
        fieldType.asParameterizedType().toString(); // this equals "java.util.ArrayList"
        fieldType.asParameterizedType().typeName(); // this equals "ArrayList"
    }
}

Ответы [ 4 ]

23 голосов
/ 28 апреля 2011

Я столкнулся с непатентованными типами при написании пользовательского доклета под Java 1.6.Я смог это исправить, добавив метод, указанный ниже, в свой доклет.


   /**
    * NOTE: Without this method present and returning LanguageVersion.JAVA_1_5,
    *       Javadoc will not process generics because it assumes LanguageVersion.JAVA_1_1
    * @return language version (hard coded to LanguageVersion.JAVA_1_5)
    */
   public static LanguageVersion languageVersion() {
      return LanguageVersion.JAVA_1_5;
   }
1 голос
/ 11 сентября 2013

После включения режима Java 1.5 с ответом Trex, вы можете получить доступ к общим типам fieldType, используя

Type[] typeArguments = fieldType.asParameterizedType().typeArguments()
1 голос
/ 21 апреля 2011

Может ли быть вывод, что java.util.ArrayList<String>, и вы не видите часть <String>, так как ваш браузер интерпретирует ее как неизвестный тег HTML?

Вам придется экранировать <для вывода HTML.

Если это не проблема, покажите достаточно кода, чтобы мы могли воспроизвести проблему.


После просмотра вашего примера я мог бы воспроизвести его с помощью этого доклета:

package de.fencing_game.paul.examples.doclet;

import com.sun.javadoc.*;
import java.util.ArrayList;

/**
 * A test doclet to see how generic fields work.
 *
 * Inspired by the question <a href="http://stackoverflow.com/q/5731619/600500">Doclet- Get generics of a list</a> on Stackoverflow.
 */
public class GenericTestDoclet<Y> extends Doclet {

    public ArrayList<? extends Y> stringList;

    /**
     * Erstellt ein(e(n)) neu(e(n)) <code>GenericTestDoclet</code>.
     *
     */
    public GenericTestDoclet() {

    }


    public ArrayList<? extends Y> getList() {
        return stringList;
    }

    public void printType(Type fieldType, DocErrorReporter err) {
        err.printNotice("type: " + fieldType);
        if (fieldType.asParameterizedType() != null) {
            ParameterizedType paramType = fieldType.asParameterizedType();
            err.printNotice("paramType:" + paramType);
            String qualiName = paramType.qualifiedTypeName();
            err.printNotice("qualiName: " + qualiName);

            String typeName = fieldType.asParameterizedType().typeName();
            err.printNotice("typeName: " + typeName);

            Type[] parameters = paramType.typeArguments();
            err.printNotice("parameters.length: " + parameters.length);
            for(Type p : parameters) {
                err.printNotice("param: " + p);
            }
        }
        err.printNotice("");
    }


    public void listFields(ClassDoc classDoc, DocErrorReporter err) {
        FieldDoc[] fields = classDoc.fields();
        for (int k = 0; k < fields.length; k++) {
            err.printNotice("field: " + fields[k]);
            Type fieldType = fields[k].type();
            printType(fieldType, err);
        }
    }


    public void listMethods(ClassDoc classDoc, DocErrorReporter err) {
        MethodDoc[] methods = classDoc.methods();
        for (int k = 0; k < methods.length; k++) {
            err.printNotice("method: " + methods[k]);
            Type returnType = methods[k].returnType();
            printType(returnType, err);
        }
    }



    /**
     * The entry point of the doclet.
     * @return true if all the included elements have enough documentation,
     *   false if some documentation is missing.
     */
    public static boolean start(RootDoc root) {
        GenericTestDoclet<?> d = new GenericTestDoclet<Integer>();
        for(ClassDoc clazz : root.classes()) {
            d.listFields(clazz, root);
            d.listMethods(clazz, root);
        }
        return true;
    }

}

Вывод, если он применяется к самому себе:

field: de.fencing_game.paul.examples.doclet.GenericTestDoclet.stringList
type: java.util.ArrayList
paramType:java.util.ArrayList
qualiName: java.util.ArrayList
typeName: ArrayList
parameters.length: 0

method: de.fencing_game.paul.examples.doclet.GenericTestDoclet.getList()
type: java.util.ArrayList
paramType:java.util.ArrayList
qualiName: java.util.ArrayList
typeName: ArrayList
parameters.length: 0

[more methods omitted]

Это показывает, что и здесь возвращаемые типы кажутся без параметров.

Я хотел сказать, что я ужеиспользовал этот метод для рекурсивной печати имени типа , но это показывает, что мой LaTeX-Doclet даже не использует рекурсивный метод, который я создал (вместо этого типы печатаются из дерева компилятора типа).

Но каким-то образом это должно быть возможно, поскольку Стандартному Доклету каким-то образом удается создать правильный вывод .

0 голосов
/ 20 апреля 2011

Предполагая, что ArrayList является полем члена вашего класса, похоже, что следующий ответ предоставит то, что вам нужно.

Фрагмент кода из этого ответа показывает общую идею (но взгляните на этот вопрос / ответ):

Field stringListField = Test.class.getDeclaredField("stringList");
ParameterizedType stringListType = (ParameterizedType) stringListField.getGenericType();
Class<?> stringListClass = (Class<?>) stringListType.getActualTypeArguments()[0];
System.out.println(stringListClass); // class java.lang.String.
...