我有一个 Java 类,其属性可以是字符串、 boolean 值或列表。 声明该属性类型的最佳方法是什么?知道我只能在运行时知道它的类型。
我的第一个方法是使用 Object 类型定义该属性,但不确定是否有更好的方法来实现此目的。
private final String expression;
private Object expressionValue;
ParsedExpression(String expression, Person person) {
this.expression= expression;
expressionEvaluator(person);
}
private void expressionEvaluator(Person person) {
switch (this.expression) {
case "name":
expressionValue = person.getName();
break;
case "adult":
expressionValue = person.isAdult();
break;
case "addresses":
expressionValue = person.getAddresses();
break;
default:
throw new RuntimeException("Property does not exist on type Person");
}
}
最佳答案
如果您的类型很少并且不打算更改它们,您可以使用带有私有(private)构造函数的泛型类和一些工厂方法,这些方法允许仅使用指定的类型参数创建实例:
public final class ExpressionValue<T> {
private final T value;
private ExpressionValue(T value) {this.value = value;}
public Optional<String> getAsString() {
return (value instanceof String) ? Optional.of((String)value) : Optional.empty();
}
public Optional<Boolean> getAsBoolean() {
return (value instanceof Boolean) ? Optional.of((Boolean) value) : Optional.empty();
}
// in this context empty collection and empty optional mean different things
@SuppressWarnings("OptionalContainsCollection")
public Optional<List<?>> getAsList() {
return (value instanceof List) ? Optional.of((List<?>) value) : Optional.empty();
}
public void use(Consumer<? super String> stringUser, Consumer<? super Boolean> booleanUser, Consumer<? super List<?>> listUser) {
getAsString().ifPresent(stringUser);
getAsBoolean().ifPresent(booleanUser);
getAsList().ifPresent(listUser);
}
public static ExpressionValue<String> fromString(String string) {
return new ExpressionValue<>(string);
}
public static ExpressionValue<Boolean> fromBoolean(boolean bool) {
return new ExpressionValue<>(bool);
}
public static ExpressionValue<List<?>> fromList(List<?> list) {
return new ExpressionValue<>(list);
}
}
<小时/>
如果您有许多可用类型或需要更灵活的类型,您可以使用分层方法。在这种情况下,您需要创建一个具有常见 String、boolean 和 List 方法的接口(interface),然后使用所有可用的类型参数创建该接口(interface)的实现。它可能看起来像这样:
public interface ExpressionValue<T> {
boolean check();
}
public abstract class ExpressionValueSkeleton<T> implements ExpressionValue<T> {
private T value;
public ExpressionValueSkeleton(T value) {
this.value = value;
}
protected T getValue() {
return value;
}
}
public class StringExpressionValue extends ExpressionValueSkeleton<String> {
public StringExpressionValue(String value) {
super(value);
}
@Override
public boolean check() {
return !getValue().isEmpty();
}
}
public class BooleanExpressionValue extends ExpressionValueSkeleton<Boolean> {
public BooleanExpressionValue(Boolean value) {
super(value);
}
@Override
public boolean check() {
return getValue();
}
}
public class ListExpressionValue<E> extends ExpressionValueSkeleton<List<E>> {
public ListExpressionValue(List<E> value) {
super(value);
}
@Override
public boolean check() {
return !getValue().isEmpty();
}
}
如果您想执行一些仅适用于某些类型的操作,您可以使用 Acyclic Visitor pattern .
关于编译时类型未知的 Java 类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57136163/