[英]How do I define a generic member variable in an enum?
我想引用一個枚舉方法來檢索算法的 class 以便我可以延遲加載算法的新實例以用於策略設計模式。
在此示例中,我使用枚舉來引用計算 Fibonacci 數的三個不同策略類: RecursiveFibonacciGenerator
、 IterativeFibonacciGenerator
和MemoizedFibonacciGenerator
(所有這些都繼承自FibonacciGenerator
)。
代碼(帶有意圖注釋的生成錯誤的行)如下:
package com.example.strategy;
public class Fibonacci {
private enum Algorithm {
RECURSIVE (RecursiveFibonacciGenerator.class),
ITERATIVE (IterativeFibonacciGenerator.class),
MEMOIZED (MemoizedFibonacciGenerator.class);
private final Class<T> algorithmClass; // Declare class of same type as constructor
private final T instance; // Declare instance of class defined in constructor
private <T extends FibonacciGenerator> Algorithm(Class<T> algorithmClass) {
this.algorithmClass = algorithmClass;
}
public T getInstance() {
if (this.instance == null) {
this.instance = this.algorithmClass.newInstance();
}
return this.instance;
}
}
public Integer getTerm(Integer termNumber) {
profileGenerator(termNumber, Algorithm.RECURSIVE);
profileGenerator(termNumber, Algorithm.ITERATIVE);
return profileGenerator(termNumber, Algorithm.MEMOIZED);
}
private Integer profileGenerator(Integer termNumber, Algorithm algorithm) {
System.out.print("Computing term using " + algorithm.toString() + " algorithm... ");
Long startTimeMilliseconds = System.currentTimeMillis();
Integer term = algorithm.getInstance().generateTerm(termNumber);
Long endTimeMilliseconds = System.currentTimeMillis();
Long computationTimeMilliseconds = endTimeMilliseconds - startTimeMilliseconds;
System.out.println("term computed in " + computationTimeMilliseconds + " milliseconds");
}
}
我想知道如何使用這個enum
構造函數來存儲Class<T>
類型的成員變量。
編輯:添加完整代碼以闡明意圖
public enum Algorithm {
RECURSIVE(FibonacciGenerator.RecursiveFibonacciGenerator.class),
ITERATIVE(FibonacciGenerator.IterativeFibonacciGenerator.class),
MEMOIZED(FibonacciGenerator.MemoizedFibonacciGenerator.class);
private final Class<? extends FibonacciGenerator> algorithmClass;
private <T extends FibonacciGenerator> Algorithm(Class<T> algorithmClass) {
this.algorithmClass = algorithmClass;
}
}
這樣做是你想要的嗎?
另一種選擇是使用 class 的實例,但經過進一步思考,我認為這是一個壞主意。 如果您要使用 class 的實例,那么為什么首先需要枚舉?
嘗試提供一個真實實例而不是 class:
public enum Algorithm {
RECURSIVE (new RecursiveFibonacciGenerator()),
ITERATIVE (new IterativeFibonacciGenerator()),
MEMOIZED (new MemoizedFibonacciGenerator());
private <T extends FibonacciGenerator> Algorithm(T algorithm) {}
}
普勞是對的。 你可以聲明和初始化一個成員變量,就好像它是一個 class 而不是一個枚舉:
private final FibonacciGenerator _instance;
private Algorithm(FibonacciGenerator instance) {
_instance = instance;
}
然后通過公共的 getFibonacciGenerator() 方法返回它。 請注意,如果您存儲實例而不是 Class,則無需使用 generics。 並記住將字段聲明為“final”
我不確定我是否很好地理解了這個問題,但是如果您只是想將策略保留為成員變量:
public enum Algorithm {
RECURSIVE (RecursiveFibonacciGenerator.class),
ITERATIVE (IterativeFibonacciGenerator.class),
MEMOIZED (MemoizedFibonacciGenerator.class);
private Class<? extends FibonacciGenerator> strategy;
private Algorithm(Class<? extends FibonacciGenerator> algorithmClass) {
this.strategy = algorithmClass;
}
Class<? extends FibonacciGenerator> getStrategy() {
return strategy;
}
}
我最終得到以下代碼:
package com.example.strategy;
public class Fibonacci {
private enum Algorithm {
UNDEFINED (null),
RECURSIVE (RecursiveFibonacciGenerator.class),
ITERATIVE (IterativeFibonacciGenerator.class),
MEMOIZED (MemoizedFibonacciGenerator.class);
private final Class<? extends FibonacciGenerator> algorithmClass;
private FibonacciGenerator instance;
private <T extends FibonacciGenerator> Algorithm(Class<T> algorithmClass) {
this.algorithmClass = algorithmClass;
}
public FibonacciGenerator getInstance() {
if (this.instance == null) {
try {
this.instance = this.algorithmClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return this.instance;
}
}
public Integer getTerm(Integer termNumber) {
return profileGenerator(termNumber, Algorithm.MEMOIZED);
}
private Integer profileGenerator(Integer termNumber, Algorithm algorithm) {
System.out.print("Computing term using " + algorithm.toString() + " algorithm... ");
Long startTimeMilliseconds = System.currentTimeMillis();
Integer term = algorithm.getInstance().generateTerm(termNumber);
Long endTimeMilliseconds = System.currentTimeMillis();
Long computationTimeMilliseconds = endTimeMilliseconds - startTimeMilliseconds;
System.out.println("term computed in " + computationTimeMilliseconds + " milliseconds");
return term;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.