2016-12-22 6 views
1

Может ли кто-нибудь объяснить концепцию этого кода? Я не знаю, что искать или с чего начать? Я хотел бы больше узнать об этом типе программирования.Интерфейс Java и метод обратного вызова

private static interface A { 
    void apply(String name, int i, int j); 
} 
private final A method_A = (name, i, j) -> methodOne(name, i, j); 
private final A method_B = (name, i, j) -> methodTwo(name, i, j); 
public void methodOne(String name, int i, int j){ 
    // do something 
} 
public void methodTwo(String name, int i, int j){ 
    // do some other thing 
} 

Благодаря

ответ

1

Ваш код может фактически быть simplfied к этому:

private static interface A { 
    void apply(String name, int i, int j); 
} 
private final A method_A = this::methodOne; 
private final A method_B = this::methodTwo; 
public void methodOne(String name, int i, int j){ 
    // do something 
} 
public void methodTwo(String name, int i, int j){ 
    // do some other thing 
} 

Две переменные method_A и method_B только регулярные переменные, которые имеют тип A. Реальная особенность в этом - это значение, которое вы назначаете переменным - this::methodOne.

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

A имеет только один метод, поэтому вы можете рассматривать его как тип, который «хранит» метод. Я объясню, почему.

До Java 8, можно было бы написать что-то вроде этого:

private final A method_A = new A() { 
    @Override 
    public void apply(String name, int i, int j) { 
     EnclosingClass.this.methodOne(name, i, j); 
    } 
}; 

Вы создать анонимный класс, который имеет только метод apply. Видеть? Разве объект method_A не хранит ничего, кроме реализации метода?

Поскольку Java 8, вы можете вместо этого написать этот лямбда-выражение:

private final A method_A = this::methodOne; 

Как вы можете догадаться, к настоящему времени, все это синтаксический сахар. Вы в основном говорите, что method_A будет хранить methdOne. Затем вы можете пройти method_A, и вы фактически передаете реализацию метода!

Новый поток API использует это и позволяет делать такие вещи, как:

someList.stream().forEach(System.out::println); 
+0

Благодарим вас за объяснение. Яркая комбинация интересна! – theeminence

+0

@theeminence Если вы считаете, что ответ отвечает на ваш вопрос, подумайте о том, чтобы принять его, нажав на галочку. – Sweeper

+0

Я принял ваш ответ – theeminence

2

Поскольку Java 8, интерфейсы с одним не по умолчанию метод может быть выражен как lambda-expressions. Эти интерфейсы также называются функциональными интерфейсами.

Ваш код создает два экземпляра интерфейса A в качестве таких лямбда-выражений, которые реализованы в качестве адаптеров для методов methodOne и methodTwo.

В основном это более компактный способ написания

... 

private final A method_A = new A{ 
    public void apply(String name, int i, int j){ 
     methodOne(name, i, j); 
    } 
}; 

private final A method_B = new A{ 
    public void apply(String name, int i, int j){ 
     methodOne(name, i, j); 
    } 
}; 

... 
+0

Спасибо за объяснение. Ссылка, которую вы предоставили, также подробно объясняет многое. – theeminence

Смежные вопросы