Java 绕过类型检查

Java 绕过类型检查,java,types,Java,Types,这是一个非常糟糕的OO,但我不想把它放在任何类型的代码中,除了编码人员自己之外,任何人都会使用它——除了编码人员的测试之外,它永远不能被调用 我面临的问题是:我有一系列外部定义的类。我不能以任何方式修改它们(当然,除了我可以子类化或调用它们)。它们有多种名称,但不扩展任何超类(对象除外),也不实现任何接口。然而,我所知道的是,它们都有一个名为“call”的方法 为了进行测试,我试图编写调用这些类的任何一个调用方法的代码。但是,当然,我不能只说Object.call(),因为调用不是为每个对象定义

这是一个非常糟糕的OO,但我不想把它放在任何类型的代码中,除了编码人员自己之外,任何人都会使用它——除了编码人员的测试之外,它永远不能被调用

我面临的问题是:我有一系列外部定义的类。我不能以任何方式修改它们(当然,除了我可以子类化或调用它们)。它们有多种名称,但不扩展任何超类(对象除外),也不实现任何接口。然而,我所知道的是,它们都有一个名为“call”的方法

为了进行测试,我试图编写调用这些类的任何一个调用方法的代码。但是,当然,我不能只说Object.call(),因为调用不是为每个对象定义的

基本上,这将起作用:

MyClassOne classOne = new MyClassOne();
MyClassOneInput classOneInput = new MyclassOneInput();

classOne.call(classOneInput);
但这不会:

Object clazz = getClassFromElsewhere();
Object clazzInput = getClassInputFromElsewhere();

clazz.call(clazzInput).
显然,因为Java是一种强类型语言

但是,为了让每个在这个系统上工作的人都能更快地进行10倍的测试,我能不能绕过这个问题,对任何类和任何ClassInput使用“call”方法?如果它生成异常,或者如果传递了错误的类,则完全中断,我没有问题

请帮助我违反对象定向。

使用

  • 使用
    getClass()
  • 使用
    getMethod()
  • 如果找到,在对象上调用它
  • e、 g

    然后

    我也会考虑查看动态JVM语言(JRube,Jython,Groovy),在这种情况下,这样做可能看起来不那么“坏OO”,感觉更自然

    < P>这是一个很好的用法。这是一个伪代码示例,但看起来像这样

     Object obj = getExternalObject();
     Method meth = obj.getClass().getDeclaredMethod("call");
     meth.invoke(obj);
    

    您可以使用反射来实现这一点。 查看

    下面是一个简单的例子:

    MyClassOne classOne = new MyClassOne();
    MyClassOneInput classOneInput = new MyClassOneInput();
    Method m = classOne.getClass().getMethod("call", MyClassOneInput.class);
    m.invoke(classOne, classOneInput);
    

    注意:您可以使用
    getDeclaredMethod
    获取任何方法,包括私有和受保护的方法,但是如果它们是私有/受保护的,您需要对它们调用“m.setAccessible(true)”。

    您知道吗?听起来您在寻找类似于C#4及更高版本中的关键字的功能。Java不存在这样的东西。您可以使用反射来获取类定义的方法列表。在列表中搜索“call()”并在找到时调用它。我不知道这是否是一个好主意,但我做得更糟。Java的反射正是为了实现这一目的,它被广泛应用于测试和与Web相关的开发中,在这些开发中,您或多或少地通过仅以字符串形式已知的名称来调用方法。相关问题:我正要介绍反射……很好!:-)
     Object obj = getExternalObject();
     Method meth = obj.getClass().getDeclaredMethod("call");
     meth.invoke(obj);
    
    MyClassOne classOne = new MyClassOne();
    MyClassOneInput classOneInput = new MyClassOneInput();
    Method m = classOne.getClass().getMethod("call", MyClassOneInput.class);
    m.invoke(classOne, classOneInput);