繁体   English   中英

编译时类型未知的Java类属性

[英]Java class property with type unknown at compile time

我有一个Java类,其属性可以是String,boolean或List。 声明该属性类型的最佳方法是什么? 知道我只能在运行时知道它的类型。

我的第一种方法是使用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");
        }
    }

如果类型很少,并且不打算更改它们,则可以将泛型类与私有构造函数和一些工厂方法一起使用,这些方法仅允许使用指定的类型参数创建实例:

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方法创建一个接口,然后使用所有可用的类型参数创建此接口的实现。 它可能看起来像这样:

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();
    }
}

如果要执行某些操作仅对某些类型可用,则可以使用非循环访问者模式

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM