代码之家  ›  专栏  ›  技术社区  ›  Brad Hein

当我使用getClass.getMethod(…)时,它是“反射”吗?

  •  2
  • Brad Hein  · 技术社区  · 14 年前

    我已经写了一些蓝牙应用程序,但我从未见过 this particular approach 直到最近。在他们使用的示例中 device.getClass().getMethod("createRfcommSocket", new Class[] { int.class }); 在我看来,这是一个很长的路要说 BluetoothSocket bs = createRfcommSocket(... .

    他们的方法有什么不同

    Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
    sock = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));
    

    和我的

    sock = createRfcommSocket(.....
    

    是否有理由使用其中一个?

    谢谢你

    6 回复  |  直到 11 年前
        1
  •  1
  •   reinierpost    14 年前

    是的,使用getclass等是反射。

    不同的是,如果您错误地输入方法名或犯了类似的错误,您可以从IDE和编译器获得帮助,而代码的作者则是他们自己的。

    可能他们所处的情况是,在编译时调用的方法不可用,在允许在运行时加载新插件的软件环境中可能是这样。但在这种情况下,您不会期望看到方法名和其他细节硬编码到代码中。

    对于我来说,您示例的文本看起来像糟糕的编程。

        2
  •  1
  •   Andrzej Doyle    14 年前

    不知道确切的细节,我能提供的一个原因是他们的方法有一种鸭子打字。不管对象的编译时类是什么,只要它有一个具有正确签名的方法,就可以调用它。

    一般来说,我认为鸭子打字在Java中不是一个很好的习惯用法。然而,这种方法可能还有其他的理由。特别是,它意味着此代码不会在编译时依赖于 device 的班级。例如,这是摆脱循环依赖性的一种方法,而附加的方法使编译步骤更松散地耦合。

    但从更广泛的意义上来说,如果你的方法 作品 我看不出有什么问题。使用反射是 通常 一种本质上的变通方法,用于一些你不能用更惯用的方式做的事情。

        3
  •  1
  •   hackbod    14 年前

    注意,反射使使用不属于SDK的平台的实现细节变得非常容易,因为它绕过了编译时检查。不应该有这样的理由使用反射来访问平台API,除非在向后兼容性的情况下,您希望应用程序在没有该API的平台的旧版本上运行。无论什么时候您这样做,您都应该非常小心地确保您正在访问的内容实际上是SDK的一部分。

        4
  •  1
  •   Community CDub    7 年前

    这里的答案是正确的,但是使用反射的具体原因是 作为一种解决办法 到周围的问题 createRfcommSocketToServiceRecord .

    我之所以这么做是因为其他人说这是在修复他们的连接问题。

    here here 更多信息。不过,我认为这个错误已经被修复了,因为 创建rfcommsockettoservicerecord (没有任何解决方法)在我的Android OS 2.2 Nexus One上运行良好。

        5
  •  0
  •   Andrew Barber Eric Lafortune    12 年前

    如果您正在检查该运行时对象中是否存在该方法-而不引发任何异常(例如,基于给定变量的运行时父类是不同的-例如,外部驱动程序),那么无论如何,您必须添加更多的行..直接调用这样的方法或按名称检索会导致在缺少的情况下引发异常。

    如果不是——那么

    不应该这样写。如果您已经可以访问该对象,则调用方法..句点。

    @MxRider,很高兴您做得对……这可能是滥用反射API的一个很好的例子。但是你可能想考虑一下,最初的作者是不是想把我上面解释过的场景固定下来。

        6
  •  0
  •   ksu    11 年前

    为我做多点蓝牙连接时,只有反射方法有效吗? 做多点连接有困难的人应该尝试反射法。