【问题标题】:Java dynamic method return typeJava动态方法返回类型
【发布时间】:2016-03-05 08:31:05
【问题描述】:

编辑 我本来应该为任何试图帮助回答这个问题的人提到这一点,但这个方法(File1.java 上的getList(String variable))实际上是一个被调用的 RESTful 端点当客户端应用程序向调用方法的类上的任何路径发送 GET 请求时。

我有一个将字符串变量作为参数的方法。我试图实现的功能是,基于该字符串变量的值,该方法将构造两个不同列表中的 1 个,并返回该列表。这可能吗?我尝试使用通用方法,例如从this stackoverflow question 开始的第三个答案中的人,但我可能没有正确实施它,因为我得到了Type parameter [GenericType] not a class or parameterized type whose raw type is a class IllegalArgumentException。这是我的代码以及我走了多远:

File1.java - 为简洁起见省略了一些内容

@Component
public class File1{

    private File2 file2;

    @Autowired
    private File1(File2 file2) {
        this.file2 = file2;
    }

    public <GenericType> GenericType getList(String variable) {
       return (GenericType)this.file2.getList(variable);
    }
}

File2.java - 为简洁起见省略了一些内容

@Component
public class File2 {
    public <GenericType> GenericType getList(String variable) {
           List<SomeClass> listA = new ArrayList<>();
           List<SomeOtherClass> listB = new ArrayList<>();
        if(variable.equals("something")) {
           //build listA...
        }
        else {
           //build listB instead...
        }
        if(variable.equals("something"))
           return (GenericType) listA;
        else
           return (GenericType) listB;
    }
}

SomeClass.java

public class SomeClass{
    public String string;
    public List<NestedList1> nestedList1 = new ArrayList<>();
    public List<NestedList2> nestedList2 = new ArrayList<>();

    public SomeClass(String string, List<NestedList1> nestedList1 , List<NestedList2> nestedList2) {
        this.string= string;
        this.nestedList1 = nestedList1 ;
        this.nestedList2 = nestedList2 ;
    }
}

SomeOtherClass.java

public class SomeOtherClass{
    public String string;
    public List<NestedList3> nestedList3 = new ArrayList<>();

    public SomeOtherClass(String string, List<NestedList3> nestedList3) {
        this.string = string;
        this.nestedList3 = nestedList3;
    }
}

@component 和 @autowired 注释只是弹簧配置的东西,所以你可以忽略它,因为它与问题无关。无论如何,我觉得这比我想象的要简单得多,但我对 Java 还是很陌生,这是我第一次使用泛型方法。如果有帮助,返回的列表本身就不是动态的。此方法应仅且始终返回这两个特定列表中的 1 个。

【问题讨论】:

  • 这是我见过最长的演员表
  • 这有点多余。我可以编辑它,但这仍然不能解决我原来的问题。
  • 在您的情况下,我会考虑使用通配符?,例如list&lt;?&gt;。是的,(List&lt;? extends SomeOtherClass&gt;)(List&lt;SomeOtherClass&gt;) 完全是多余的
  • 调用File1.getList() 的行是什么样的,包括任何相关的类型声明?
  • @Douglas 我忽略了这一点,认为它不相关,但在上下文中,这实际上是我设置的一个安静的端点。确切地说是 GET 请求。在这个类上定义了一个路径,如果用户使用 GET 请求点击这个端点,该方法就会被调用。

标签: java spring arraylist


【解决方案1】:

为了使这个技巧发挥作用,Java 需要有一种方法,以某种方式来确定 GenericType 实际是什么类型。当您在代码中显式调用方法并将其结果分配给变量时,如您链接到的答案中,它可以推断出 GenericType 是变量的类型。这是在编译时完成的,Java 也可以。

像您正在制作的宁静端点没有那个。您的 REST 提供者必须在运行时使用反射来确定类型,而这样做所需的信息并不存在。一方面,没有非反射的代码调用来推断类型信息,另一方面,类型擦除无论如何都会在编译期间丢弃它。

幸运的是,实际上没有必要这样做。两个可能的返回值都是List 类型。只需将方法声明为返回List。

【讨论】:

  • 谢谢!我认为这无关紧要,但也许我应该提到这是我的问题中的一个安静的端点,而不仅仅是任何 java 应用程序。只需将端点的返回类型更改为通用的List 类型即可。
【解决方案2】:

Java 不能做到这一点(一般来说)。

用法是:

List<?> list = file1.getList(s);

然后动态检查内容。

为此,最好将类不仅仅在列表元素中(可能为空),而是在列表本身中。

一般来说,创建一个包含两个不同类型列表的类,然后返回其中一个为空的列表。

【讨论】:

    猜你喜欢
    • 2013-08-19
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多