Doclet-获取列表的泛型

发布于 2024-11-02 15:29:12 字数 918 浏览 2 评论 0原文

我正在编写一个扩展 com.sun.javadoc.Doclet 的 doclet。

当我想要将 ArrayList 记录为方法的字段时,我想获取泛型的类型(例如,在记录 ArrayList 时,我想获取这是一个列表的信息包含字符串)。

我只能得到信息,这是一个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"
    }
}

I am writing a doclet extending com.sun.javadoc.Doclet.

When i want want to document an ArrayList as a field of a method i want to get the type of the generic (e.g. when documenting an ArrayList<String> I want to get the information that this is a list containing Strings).

I am only able to get the information, that this is a ArrayList. Even when calling

ParameterizedType paramType = fieldType.asParameterizedType();

I am only getting java.util.ArrayList and not the type of the generic.

Does someone know how to get the generic type of the list?

Here is the example code:

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"
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

怀念你的温柔 2024-11-09 15:29:12

在 Java 1.6 下编写自定义 doclet 时,我遇到了泛型在类型上丢失的问题。我可以通过将以下方法添加到我的 doclet 来修复它。


   /**
    * 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;
   }

I was running into generics being lost on types while writing a custom doclet under Java 1.6. I was able to fix it by adding the method below to my doclet.


   /**
    * 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;
   }
江南月 2024-11-09 15:29:12

是否输出是 java.util.ArrayList 并且您没有看到 部分,因为您的浏览器将其解释为未知的 HTML标签?

对于 HTML 输出,您必须转义 <

如果这不是问题,请显示足够的代码,以便我们可以重现问题。


看到你的示例后,我可以用这个 doclet 重现它:

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 实际上甚至没有使用我创建的递归方法(而是类型为 从该类型的编译器树打印)。

但不知何故,这必须是可能的,因为不知何故标准 Doclet 设法创建正确的输出

Could it be that the output is java.util.ArrayList<String> and you don't see the <String> part since your browser interprets it as an unknown HTML tag?

You will have to escape the < for HTML output.

If this is not the problem, show enough code so we can reproduce the problem.


After seeing your example, I could reproduce it with this doclet:

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;
    }

}

The output, if applied on itself:

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]

It shows that also return types seem to be parameterless here.

I wanted to say that I already used this method to print recursively a type name, but it shows that my LaTeX-Doclet actually is not even using the recursive method I created (instead the types are printed from the compiler tree of the type).

But somehow this has to be possible, since somehow the Standard Doclet manges to create the right output.

心碎的声音 2024-11-09 15:29:12

使用 Trex 的答案启用 Java 1.5 模式后,您可以使用以下方式访问 fieldType 的通用类型

Type[] typeArguments = fieldType.asParameterizedType().typeArguments()

After enabling Java 1.5 mode with Trex's answer, you can access the generic types of fieldType using

Type[] typeArguments = fieldType.asParameterizedType().typeArguments()
诗酒趁年少 2024-11-09 15:29:12

假设 ArrayList 是您的类的成员字段,它看起来像以下答案< /a> 将提供您需要的内容。

该答案中的代码片段显示了总体思路(但请看一下该问题/答案):

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.

Assuming the ArrayList is a member field of your class, it looks like the following answer will provide what you need.

A snippet of the code from that answer shows the general idea (but take a look at that question/answer):

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文