Java анонимный внутренний класс, вызывающий метод супертипов вмещающего типа - PullRequest
0 голосов
/ 11 октября 2018

Я приведу пример для установки некоторого контекста здесь, поэтому у меня есть два интерфейса, каждый из которых наследует один и тот же родительский интерфейс и определяет свою собственную реализацию абстрактного метода родительского интерфейса.

interface A
{
    Set a();
}

interface B extends A
{
    @Override
    default Set a()
    {
        return null;
    }
}

interface C extends A
{
    @Override
    default Set a()
    {
        return null;
    }
}

В интерфейсе, называемомD, Реализация создает анонимный внутренний класс, который затем должен вызывать реализацию супертипов (B и C) a().

interface D extends B, C
{
    @Override
    default Set a()
    {
        return new HashSet()
        {
            {
                final int totalSize = D.this.B.super.a().size() + D.this.C.super.a().size();
            }
        };
    }
}

Проблема в том, что выражения D.this.B.super.a() и D.this.C.super.a() не удалось успешно скомпилироваться, что случилось?

Кстати, спасибо за ваши усилия.

1 Ответ

0 голосов
/ 11 октября 2018

Java позволяет вам получить доступ к конкретным реализациям интерфейса с помощью синтаксиса:

InterfaceName.super.method()

Однако внутри анонимного класса можно получить включающий экземпляр с D.this.Нельзя объединять эти синтаксисы, чтобы сначала получить включающий экземпляр, а затем его реализации суперинтерфейса.

Решение здесь состоит в том, чтобы переместить объявление totalSize за пределы анонимного класса, чтобы вы могли получить доступ креализации суперинтерфейса.Анонимный класс по-прежнему сможет ссылаться на локальную переменную totalSize, поскольку она final.(Он все еще мог бы получить к нему доступ, если бы он был фактически окончательным - не final, но никогда не переназначался.)

final int totalSize = B.super.a().size() + C.super.a().size();
return new HashSet()
{
     // Anonymous class implementation here.
     // You can refer to totalSize.
};

Возможно, для краткости вы не указали дженерики, но в случае, если вы этого не сделали, вы захотите включить параметры типа для Set и HashSet.

...