代码之家  ›  专栏  ›  技术社区  ›  Blessed Geek

如何从一般特定的类中获取类文本

  •  9
  • Blessed Geek  · 技术社区  · 14 年前

    有这样的方法需要类文本作为参数。

    Collection<EmpInfo> emps =  
      SomeSqlUtil.select(  
      EmpInfo.class,  
      "select * from emps");
    

    GWT.create(Razmataz.class);
    

    当我需要提供诸如

    EmpInfo<String>
    Razmataz<Integer>
    

    以下是错误的语法

    Collection<EmpInfo<String>> emps =  
      SomeSqlUtil.select(  
      EmpInfo<String>.class,  
      "select * from emps");
    

    GWT.create(Razmataz<Integer>.class);
    

    因为你不能像这样做语法

    Razmataz<Integer>.class
    

    那么,我如何才能从

    empinfo<字符串>
    Razmataz<integer>
    

    所以我可以将它们作为参数提供给需要类文本的方法?

    进一步信息

    好吧,我承认我主要是为了GWT。

    我有一对GWT RPC接口razmataz。(仅供参考,GWT RPC接口必须在服务器客户端对中定义)。我计划使用相同的接口对来通信,不管它是字符串、整数、布尔值等。

    GWT.create(Razmataz) 对于 Razmataz<T> 抱怨说,由于我没有指定t,GWT编译器将其视为对象。那么GWT编译器将不接受对象类。它需要比成为一个对象更具体。

    所以,我似乎没有办法告诉GWT.create什么是T,因为类文本是运行时概念,而泛型是编译时概念,对吧?

    3 回复  |  直到 14 年前
        1
  •  7
  •   Péter Török    14 年前

    引用 Java Generics and Collections 第7.2节:

    类文本也受到限制;甚至在语法上为类文本中的类型提供类型参数都是无效的。因此,以下片段是非法的:

    class ClassLiteral {
      public Class<?> k = List<Integer>.class;  // syntax error
    }
    

    事实上,Java的语法使得一个短语(如前一个短语)难以解析,它可能引发语法错误的级联[…]

    这个语法问题导致不规则。在其他需要可重设类型的地方,您可以提供原始类型(例如 List )或带有无边界通配符的参数化类型(例如 List<?> )但是,对于类标记,必须提供一个原始类型;甚至不会出现无边界通配符。替代 List<Integer> 具有 名单&?gt; 在前面的代码中,会导致类似的错误级联。

    所以,您别无选择,只能在类标记中使用原始类型,比如

    GWT.create(Razmataz.class);
    
        2
  •  3
  •   Bozho    14 年前

    你不能。

    使用不安全的石膏:

    Collection<EmpInfo<String>> emps = 
         (Collection<EmpInfo<String>>) someMethod(EmpInfo.class);
    
        3
  •  3
  •   Blessed Geek    14 年前

    有人在这里留下了一个简短的答案,我正要选择它作为答案。不幸的是,那个人删除了那个答案。如果那个人愿意重新发布那个答案让我选择的话。同时,让我陈述一下这个答案以及我如何利用它。

    这是我应该想到的 ,


    Interface RazmatazString extends Razmataz<String>{}
    
    GWT.create(RazmatazString.class);
    

    根据删除的答案,

    我会有一个基本的razmataz接口对做很多事情,这是我太懒了重复。

    Abstract class Razmatazer{
    .....
    
      Interface Razmataz<T>{
      // does a lot of RPC stuffs
      }
    
      Interface RazmatazAsync<T>{
      // does a lot of RPC stuffs
      }
    
      RazmatazAsync<?> razmatazAsyncRPC;
    }
    

    概念不是在基类上实例化razmatazasyncRpc句柄,而是在派生类上实例化。

    t=字符串

    StringRazmatazer extends Razmatazer{
    
      Interface RazmatazStringAsync extends RazmatazAsync<String>{}
      Interface RazmatazString extends Razmataz<String>{}
    
      razmatazAsyncRPC = GWT.create(RazmatazString.class);
    }
    

    否则,我必须在字符串、映射、布尔值、整数等的各种T参数值上重复~100行代码,对于razmataz和razmatazync,每个代码重复~50行。

    克服这个障碍的基本前提是——我懒得重复这些台词。