当前位置: 首页 > 面试题库 >

在Java中使用反射来创建引用变量类型设置为新实例类名称的新实例?

钱黎明
2023-03-14
问题内容

我所考虑的所有示例都显示了如何创建一个未知实现的新实例,并将该实现投射到其接口。问题在于,现在您不能在实现类上调用任何新方法(只能重写),因为您的对象引用变量具有接口类型。这是我所拥有的:

Class c = null;
try {
    c = Class.forName("com.path.to.ImplementationType");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}
InterfaceType interfaceType = null;
try {
    interfaceType = (InterfaceType)c.newInstance();
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}

如果我仅引用“
com.path.to.ImplementationType”,而我不知道该类型可能是什么(它来自配置文件),那么如何使用类名将其强制转换为实施类型?这有可能吗?


问题答案:

这行似乎总结了您的问题的症结所在:

问题在于,现在您不能在实现类上调用任何新方法(只能重写),因为您的对象引用变量具有接口类型。

您非常困在当前的实现中,因为不仅必须尝试强制类型转换,还需要定义要在此子类上调用的方法的定义。我看到两个选择:

1. 如其他地方所述,您不能使用类名称的String表示形式将反映的实例转换为已知类型。但是,您可以使用String
equals()测试来确定您的类是否为所需的类型,然后执行硬编码的强制转换:

try {
   String className = "com.path.to.ImplementationType";// really passed in from config
   Class c = Class.forName(className);
   InterfaceType interfaceType = (InterfaceType)c.newInstance();
   if (className.equals("com.path.to.ImplementationType") {
      ((ImplementationType)interfaceType).doSomethingOnlyICanDo();
   } 
} catch (Exception e) {
   e.printStackTrace();
}

这看起来很丑陋,并且破坏了您拥有的漂亮的配置驱动过程。我不建议您这样做,这只是一个例子。

2. 您还有另一个选择是将您的反思从正义Class/
Object创作延伸到包括Method反思。如果可以Class从配置文件中传入的字符串创建,则还可以从该配置文件中传入方法名称,并通过反射MethodClass对象中获取其自身的实例。然后,您可以调用invoke(http://java.sun.com/javase/6/docs/api/java/lang/reflect/Method.html#invoke(java.lang.Object,java.lang.Object
…) )Method,传入您创建的类的实例。我认为这将帮助您获得所需的服务。

这是一些代码作为示例。注意,我已经为这些方法的参数进行了硬编码。您也可以在配置中指定它们,并且需要反思它们的类名以定义它们的Class对象和实例。

public class Foo {

    public void printAMessage() {
    System.out.println(toString()+":a message");
    }
    public void printAnotherMessage(String theString) {
        System.out.println(toString()+":another message:" + theString);
    }

    public static void main(String[] args) {
        Class c = null;
        try {
            c = Class.forName("Foo");
            Method method1 = c.getDeclaredMethod("printAMessage", new Class[]{});
            Method method2 = c.getDeclaredMethod("printAnotherMessage", new Class[]{String.class});
            Object o = c.newInstance();
            System.out.println("this is my instance:" + o.toString());
            method1.invoke(o);
            method2.invoke(o, "this is my message, from a config file, of course");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException nsme){
            nsme.printStackTrace();
        } catch (IllegalAccessException iae) {
            iae.printStackTrace();
        } catch (InstantiationException ie) {
            ie.printStackTrace();
        } catch (InvocationTargetException ite) {
            ite.printStackTrace();
        }
    }
}

和我的输出:

this is my instance:Foo@e0cf70
Foo@e0cf70:a message
Foo@e0cf70:another message:this is my message, from a config file, of course


 类似资料:
  • 我正在试验反射库发现:https://code.google.com/p/reflections/ 我试图实现的是扫描项目中的一个包,然后创建在该包中找到的给定类型的所有子类的实例。我使用库的方式是正确的,因为子类型返回以下内容: [class identifiers.DNSLookup,class identifiers.AliasChecker,class identifiers.Google

  • 问题内容: 可以使用反射在抽象祖先类中创建派生类的实例吗? } 问题答案: 你可以这样做 版画 一种更常见的模式是使用Cloneable 版画 但是,应避免使用两者之一。通常,还有另一种方法可以满足您的需求,因此基础不会隐式地依赖于派生。

  • 我使用反射为我的 pojo 类创建了一个实例,如下所示: 当我打印时,我得到了以下字符串: < code > com . hex gen . ro . request . createrequisitionro @ 95c 7850[trans srlno = 实际上,所有值都设置为null,我希望为类中可用的setter设置值。因为setters名称可以随时更改,所以我计划动态设置值,这样就不会

  • 问题内容: 是否可以在Java中创建泛型类型的实例?我正在根据我所看到的答案进行思考no(由于类型擦除),但是如果有人能看到我所缺少的内容,我将很感兴趣: 编辑:事实证明,超级类型令牌可以用于解决我的问题,但是它需要很多基于反射的代码,如下面的一些答案所示。 问题答案: 你是对的。你做不到。但你可以将其更改为 但这有效。以工厂模式包装它会使它更具容忍性。

  • 本文向大家介绍利用反射获取Java类中的静态变量名及变量值的简单实例,包括了利用反射获取Java类中的静态变量名及变量值的简单实例的使用技巧和注意事项,需要的朋友参考一下 JAVA可以通过反射获取成员变量和静态变量的名称,局部变量就不太可能拿到了。 其中要查看的Java类是: 以上这篇利用反射获取Java类中的静态变量名及变量值的简单实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望

  • 问题内容: 有没有一种方法可以给定类名称(动态)来创建特定类的实例,并将参数传递给其构造函数。 就像是: 的构造函数的参数在哪里? 问题答案: 是的,类似: 当然,这仅适用于单个字符串参数,但是你可以轻松地对其进行修改。 注意,类名必须是完全合格的,即包括名称空间。对于嵌套类,你需要使用美元(因为这是编译器使用的美元)。例如: 要获得该Class对象,你需要。