在方法中添加绑定到类类型参数

时间:2017-10-25 10:53:54

标签: java generics

有没有办法在具体方法中使类类型参数更窄(添加另一个绑定)?

让我们看看例子

public class Value<T>
{
    private final T value;

    public Value(T value)
    {
        this.value = value;
    }

    public <V extends T> boolean eq(V value)
    {
        return Objects.equals(this.value, value);
    }

    // here, I want to create bound that T extends Comparable<T>
    // error: type parameter cannot be followed by other bounds
    public <V extends T & Comparable<T>> boolean gt(V value)
    {
        return ((V)this.value).compareTo(value) > 0;
    }

    // here, I want to create bound that T extends String
    // error: interface expected here
    public <V extends T & String> boolean match(V value)
    {
        return ((V)this.value).equalsIgnoreCase(value);
    }

    public static void main(final String[] args)
    {
        final Value<Integer> integerValue = new Value<>(10);
        integerValue.eq(10);           // should compile
        integerValue.gt(5);            // should compile
        integerValue.match("hello");   // shouldn't compile because match operates only on String values

        final Value<String> stringValue = new Value<>("Foo");
        stringValue.eq("Foo");         // should compile
        stringValue.gt("bar");         // should compile
        stringValue.match("foo");      // should compile
    }
}

在此示例行中

integerValue.match("hello");

没有编译,这是正确的,但由于类型参数不能跟随其他边界

的限制,该类也无法编译

有没有其他方法可以实现这个目标?

3 个答案:

答案 0 :(得分:0)

使用&运算符假设V直接扩展TString,因此其中一个必须是一个接口,因为类不能直接扩展另外两个类。它对Comparable<T>无效,因为编译器不能保证类型安全与错字。

您只需使用,

// here, I want to create bound that T extends Comparable<T>
// error: type parameter cannot be followed by other bounds
public <V extends T, T extends Comparable<T>> boolean gt(V value)
{
    return ((V)this.value).compareTo(value) > 0;
}

// here, I want to create bound that T extends String
// error: interface expected here
public <V extends T, T extends String> boolean match(V value)
{
    return ((V)this.value).equalsIgnoreCase(value);
}

答案 1 :(得分:0)

类型界限不是您需要的解决方案。你需要的是子类。

my %emptyHash = ();
my %sourceHash = ();
$sourceHash{'apple'} = 'red';
$sourceHash{'orange'} = 'orange';

my $d = mergeHash(\%emptyHash, \%sourceHash);

foreach my $k (keys %$d)
{
  print "key=>". $k. "\tvalue=>". $emptyHash{$k}. "\n";
}

sub mergeHash {
  my $emptyHash = shift;
  my $sourceHash = shift;

  %$emptyHash = %$sourceHash;
  return $emptyHash;
}

然后public class Value<T> { protected final T value; public Value(T value) { this.value = value; } public boolean eq(T value) { return Objects.equals(this.value, value); } } public class ComparableValue<T extends Comparable<T>> extends Value<T> { public ComparableValue(T value) { super(value); } public boolean gt(T value) { return this.value.compareTo(value) > 0; } } public class StringValue extends ComparableValue<String> { public StringValue(String value) { super(value); } public boolean match(String value) { return this.value.equalsIgnoreCase(value); } } 变为

main

答案 2 :(得分:0)

实例方法必须可用于该类的所有实例。您不能声明仅对类的某些实例存在的方法,具有特定类型参数的方法。

您可以做的是创建一个通用的静态方法,该方法将类的实例作为参数。由于泛型类型参数现在特定于方法,因此可以限制为方法所需的内容:

public static <T> boolean eq(Value<T> obj, T value)
{
    return Objects.equals(obj.value, value);
}

public static <T extends Comparable<T>> boolean gt(Value<T> obj, T value)
{
    return obj.value.compareTo(value) > 0;
}

public static <T extends String> boolean match(Value<T> obj, T value)
{
    return obj.value.equalsIgnoreCase(value);
}