更改静态调用流程 (Java)
Change flow of static call (Java)
我有很多
Foo.a()
但现在我想根据特定条件拆分对 a() 的调用。如果可能的话,我想保持 Foo.a() 调用不变。相反,也许 Foo 可以成为管理流程的工厂,而 FooA 和 FooB 可以扩展 Foo。例如,在 Foo:
private static Class<?> foo;
static {
if (certain_criteria) {
foo = SomeUtil.getClass("FooA");
} else {
foo = FooB.class;
}
Object obj = foo.newInstance();
o = (Foo) obj;
}
...
public static void a() {
o.a(); //And this should call either FooA.a() or FooB.a()
//But a() should be accessed in a static way
}
我不能使 Foo 中的 a() 成为非静态的,因为那样我就必须将整个项目中的 100 多个调用更改为 Foo.a()。有没有解决的办法?或者更好的处理流程的方法?
我还尝试使用 foo 来调用 a(),但这会导致编译器错误,因为它的类型是 Class?>。如果我将其更改为
Class<Foo>
然后我得到
Type mismatch: cannot convert from Class<FooB> to Class<Foo>
您建议使用静态方法 Foo.a()
作为选择和调用适当实现的外观,以 class Foo
选择的可配置方式。您的具体想法似乎依赖于 Foo
的子 classes 来实现支持 Foo.a()
.
的策略模式
您将至少两个可分离的部分混为一谈:
- 实施
Foo.a()
和 的策略
- 选择和实例化特定策略的机制。
特别是,虽然您可能有理由想要使用 Foo
的子 class 部分在真实代码中表示您的策略,但在您的示例代码中没有这样的理由。那么,从示意图上看,您似乎想要这样的东西:
public class Foo {
private static FooStrategy strategy = FooStrategyFactory.createStrategy();
public static void a() {
strategy.doA();
}
}
interface FooStrategy {
void doA();
}
当然,你不需要一路走到那里。您最初的想法基本上是让 Foo
本身代替 FooStrategy
服务,并让静态初始化器服务而不是单独的 FooStrategyFactory
。这本身并没有错;我只是把它拆开来更清楚地展示每一位的作用。
您还表达了一些具体的实施问题:
If I change it to Class<Foo>
then I get
Type mismatch: cannot convert from Class to Class
我上面的方案中的等价物是声明一个 Class<FooStrategy>
类型的变量,并尝试为其分配一个 Class<FooStrategyA>
代表一个 class 实现 FooStrategy
. Class
对象的正确类型可以表示任何 class,其实例与类型 FooStrategy
的赋值兼容是 Class<? extends FooStrategy>
。无论 FooStrategy
本身是 class 还是接口,这都有效。
I can't call any classes from Foo on foo. "The method a() is undefined for the type Class"
您似乎一直在说您不能在 Class<? extends Foo>
类型的对象上调用 class Foo
的静态方法。事实上,你不能。 class Class
的对象只有 class Class
的方法。尽管您可以使用它们反射性地调用它们所代表的 classes 的方法,但这些方法不能通过 Class
实例本身直接访问。这个问题不会直接出现在我提出的方案中,但它可能出现在工厂或策略实施中。
此外,静态方法不是虚拟的。它们在编译时绑定,基于调用它们的引用 expressions 的正式类型。为了正确应用策略模式,需要的策略实现方法需要是虚拟的:非private
和非static
.
我有很多
Foo.a()
但现在我想根据特定条件拆分对 a() 的调用。如果可能的话,我想保持 Foo.a() 调用不变。相反,也许 Foo 可以成为管理流程的工厂,而 FooA 和 FooB 可以扩展 Foo。例如,在 Foo:
private static Class<?> foo;
static {
if (certain_criteria) {
foo = SomeUtil.getClass("FooA");
} else {
foo = FooB.class;
}
Object obj = foo.newInstance();
o = (Foo) obj;
}
...
public static void a() {
o.a(); //And this should call either FooA.a() or FooB.a()
//But a() should be accessed in a static way
}
我不能使 Foo 中的 a() 成为非静态的,因为那样我就必须将整个项目中的 100 多个调用更改为 Foo.a()。有没有解决的办法?或者更好的处理流程的方法?
我还尝试使用 foo 来调用 a(),但这会导致编译器错误,因为它的类型是 Class?>。如果我将其更改为
Class<Foo>
然后我得到
Type mismatch: cannot convert from Class<FooB> to Class<Foo>
您建议使用静态方法 Foo.a()
作为选择和调用适当实现的外观,以 class Foo
选择的可配置方式。您的具体想法似乎依赖于 Foo
的子 classes 来实现支持 Foo.a()
.
您将至少两个可分离的部分混为一谈:
- 实施
Foo.a()
和 的策略
- 选择和实例化特定策略的机制。
特别是,虽然您可能有理由想要使用 Foo
的子 class 部分在真实代码中表示您的策略,但在您的示例代码中没有这样的理由。那么,从示意图上看,您似乎想要这样的东西:
public class Foo {
private static FooStrategy strategy = FooStrategyFactory.createStrategy();
public static void a() {
strategy.doA();
}
}
interface FooStrategy {
void doA();
}
当然,你不需要一路走到那里。您最初的想法基本上是让 Foo
本身代替 FooStrategy
服务,并让静态初始化器服务而不是单独的 FooStrategyFactory
。这本身并没有错;我只是把它拆开来更清楚地展示每一位的作用。
您还表达了一些具体的实施问题:
If I change it to
Class<Foo>
then I getType mismatch: cannot convert from Class to Class
我上面的方案中的等价物是声明一个 Class<FooStrategy>
类型的变量,并尝试为其分配一个 Class<FooStrategyA>
代表一个 class 实现 FooStrategy
. Class
对象的正确类型可以表示任何 class,其实例与类型 FooStrategy
的赋值兼容是 Class<? extends FooStrategy>
。无论 FooStrategy
本身是 class 还是接口,这都有效。
I can't call any classes from Foo on foo. "The method a() is undefined for the type Class"
您似乎一直在说您不能在 Class<? extends Foo>
类型的对象上调用 class Foo
的静态方法。事实上,你不能。 class Class
的对象只有 class Class
的方法。尽管您可以使用它们反射性地调用它们所代表的 classes 的方法,但这些方法不能通过 Class
实例本身直接访问。这个问题不会直接出现在我提出的方案中,但它可能出现在工厂或策略实施中。
此外,静态方法不是虚拟的。它们在编译时绑定,基于调用它们的引用 expressions 的正式类型。为了正确应用策略模式,需要的策略实现方法需要是虚拟的:非private
和非static
.