Общий параметр не применяется для интерфейса - PullRequest
2 голосов
/ 08 марта 2019

Ниже приведен код, в котором я объявил два метода, тип возвращаемого значения которых является ограниченным параметром, но один основан на интерфейсе, а другой - на классе.В методе test () назначение возвращаемого типа для String завершается неудачно для метода, в котором ограниченный параметр расширяется из ожидаемого класса, но компилятор не выдает ошибку, когда ограниченный параметр основан на интерфейсе.Можете ли вы объяснить, почему это происходит?

import java.io.FileInputStream;
import java.util.function.Predicate;

public class Dummy
{
    <T extends Predicate<String>> T getBoundedByInterface()
    {
        return null;
    }

    <T extends FileInputStream> T getBoundedByClass() {
        return null;
    }
    public void test()
    {
        String compilationError = getBoundedByClass(); //Expected
        String works = getBoundedByInterface(); //No compilation error. Why?

    }
}

1 Ответ

2 голосов
/ 08 марта 2019

Компилятор Java определит, может ли тип переменной удовлетворить общий тип возвращаемого значения вызываемого метода. С таким классом, как FileInputStream, он знает, что ни один класс не может быть как FileInputStream, так и String, потому что класс не может наследоваться от более чем одного класса, поэтому это запрещено. Кроме того, мы знаем, что String также final, но это не входит в логику компилятора.

Однако с интерфейсом для подкласса возможно расширить границы и быть подклассом другого класса.

class Thing extends FileInputStream implements Predicate<String> {
    // Implementation
}

По этой причине это компилируется.

Thing works = getBoundedByInterface();

Обратите внимание, что он также работает с String, поскольку компилятор не учитывает, что String равно final.

...