反射VS静态的东西



最近,我重新构建了一个Java代码,试图尽可能消除static内容(变量和方法),并用更好的编码实践取而代之。

我也开始研究反思,并注意到它允许我做一些1的事情,起初,我只能通过static调用或引用来实现(或者,至少,我是这样看的)。

然而,虽然我一直在读到static的使用不太推荐,但它似乎与反射不一样。

所以,我想问:与其制作一个方法static并像ClassName.methodName()那样调用它,不如将其作为实例方法并由java.lang.reflect.Method.invoke()调用它,这是反射的合法使用吗?


1类似于动态访问类的内容


这里有一个代码示例:

假设情况有效(但我不想使方法static):

import static java.lang.System.out;

public class Foo
{
    private static boolean light;

    public Foo()
    {
        turnOn();
    }
    public static void turnOn()
    {
        light = true;
    }
    public static void turnOff()
    {
        light = false;
    }
    public static boolean isGreenLight()
    {
        return light;
    }
}
public class Boo
{
    public Boo()
    {
        if (Foo.isGreenLight())        // I need to access Foo.isGreenLight() from here, but cur-
        {                              // rently that method is not static (it should be to do so)
            out.println("Ok!");
        }
    }
}
public final class Main
{
    public static void main(String[] args)
    {
        final Boo boo = new Boo();
    }
}

假设情况也应该起作用(如何使用反射):

import static java.lang.System.out;
import java.lang.reflect.Method;

public class Foo
{
    private boolean light;

    public Foo()
    {
        turnOn();
    }
    public void turnOn()
    {
        this.light = true;
    }
    public void turnOff()
    {
        this.light = false;
    }
    public boolean isGreenLight()
    {
        return this.light;
    }
}
public class Boo
{
    public Boo()
    {
        if ((boolean) Class.forName("Foo").getMethod("isGreenLight", null).invoke(new Foo(), null))
        {
            out.println("Ok!");
        }
    }
}
public final class Main
{
    public static void main(String[] args)
    {
        final Boo boo = new Boo();
    }
}

预期输出(未测试):

好的!

使用反射是一种代码气味,尤其是当您所写内容背后的意图不足以保证时

在没有看到代码的情况下很难说更多,因为这只是猜测。

我会:

  • 列举一下为什么你首先拥有这些static成员的原因

  • 首先确定static修饰符是否是正确的决定:即这些成员应该是实例成员还是类成员?有问题的类的"客户端"如何使用它们?我使用的是什么模式?函数或面向对象的代码。它是否满足DRY、SOLID和KISS编程实践?

  • 考虑一下我是否首先过度设计

更重要的是:

  • 我将首先通过测试设计我的代码,这将通过用户的眼睛推动API的设计,并带来额外的好处,即您甚至在实现之前就拥有测试覆盖范围。通常情况下,当以这种方式编写代码时,我会消除这些问题,因为从用户而不是设计师的角度思考时,解决方案会更明显。它变成了一个实用主义的问题,而不是满足建筑设计的目标和哲学

相关内容

  • 没有找到相关文章