【问题标题】:Instantiate object by it's path got from annotation property通过从注释属性获得的路径实例化对象
【发布时间】:2011-10-26 13:26:03
【问题描述】:

1.有如下注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Trackable {
    String builder();
}

2.此注解的用法:

@Trackable(builder = "pkg1.SomeVO")
public class MyService

3. pkg1.SomeVO - 是 Java 对象的路径,应该在我的方面类中进一步实例化。

4.我得到了build的String值,它等于'pkg1.SomeVO'来自反射。

问题是,如何实际实例化SomeVO 对象?
我需要这样:
MyBuilder mb=new SomeVO(); 其中MyBuilder 是抽象类,已定义。

它可以是任何对象,例如。 G。 SomeVO2 等,所以我绝对不知道在我的方面(见第 3 步),应该实例化什么类。

【问题讨论】:

    标签: java reflection object path instantiation


    【解决方案1】:

    做这样的事情来获取注释值并创建类。此外,您可能希望在注释中使用默认值字段和 Class 而不是 String 以使事情变得更容易。

    for (Method m : MyService.class.getDelcaredMethods())
      if (m.getAnnotation(Trackable.class) != null) {
          String className = m.getAnnotation(Trackable.class).builder()
          Class.forName(className).newInstance();
      }
    

    如果你的类没有默认构造函数,你需要弄清楚它需要什么参数:

    for (Constructor c : Class.forName(className).getConstructors())
       if (c.getParameterTypes() == /* your expected arg types */)
           return c.newInstance(/* your args */);
    

    为确保您的课程属于某种类型(例如MyBuilder),您可以将注释设为:

    public @interface Trackable {
       Class<? extends MyBuilder> value()
    }
    

    【讨论】:

    • 好点,其实我错过了关于Class的问题。让我看看,我会尽快给你反馈。
    • 方法放在TYPE,而不是METHOD。不过,我仍然收到了这一点:)
    • Class.forName(className).newInstance() 创建一个新实例。我如何实际使用它来设置特定字段?
    • 如果您没有默认构造函数,则需要使用 args 调用构造函数(参见修订后的答案)。你也可以使用反射来调用 setter。
    • Garrett Hall,是的,我理解你。我提到了,我怎么知道 Class.forName(className).newInstance() 是 SomeVO 对象。因为我需要以方式实例化它:MyBuilder mb=new SomeVO(),MyBuilder 是抽象类在哪里
    【解决方案2】:

    假设通过路径,你的意思是你的类所在的包(希望在类路径上)。

    String myClass = getClassNameFromAnnotationReflectively(); // YOU define this method...
    Class<SomeVO> someVoClass = Class.forName(myClass);
    SomeVO someVo = someVoClass.newInstance();
    

    如果您的class 没有默认构造函数,您可以使用getConstructor(Class&lt;?&gt; ...) 找到正确的构造函数(您可以在其中传递您正在寻找的构造函数的参数类型),然后调用@987654322 @ 对此(传递实际值)。

    Class 对象上有很多有趣的方法可供使用。我建议你看看。

    【讨论】:

    • nicholas,我不知道,它是 SomeVO 类。我的意思是,你的代码的第一行假设,我们绝对应该知道,它是 SomeVO。
    • @sergionni,在您的问题中,第 4 点表明您已经使用反射获得了 builder 的字符串值。使用 String 并使用它而不是我示例中的硬编码。
    猜你喜欢
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    • 2011-07-02
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    相关资源
    最近更新 更多