Что это за особенность?

Я не мог понять следующий фрагмент кода:

Unirest.setObjectMapper(new ObjectMapper() {
    private com.fasterxml.jackson.databind.ObjectMapper jacksonObjectMapper
            = new com.fasterxml.jackson.databind.ObjectMapper();

    public <T> T readValue(String value, Class<T> valueType) {
        try {
            return jacksonObjectMapper.readValue(value, valueType);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String writeValue(Object value) {
        try {
            return jacksonObjectMapper.writeValueAsString(value);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
});

ObjectMapper - это интерфейс. Почему я могу определить это с помощью нового ключевого слова? Это похоже на функцию Java 8, верно?

2 ответа

Решение

Это очень распространенная практика в Java, и то, что вы видите, называется анонимными классами. Этот же код можно заменить следующим:

private class ObjectMapperChild extends ObjectMapper
{
private com.fasterxml.jackson.databind.ObjectMapper jacksonObjectMapper
            = new com.fasterxml.jackson.databind.ObjectMapper();

    public <T> T readValue(String value, Class<T> valueType) {
        try {
            return jacksonObjectMapper.readValue(value, valueType);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String writeValue(Object value) {
        try {
            return jacksonObjectMapper.writeValueAsString(value);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}

ObjectmapperChild objMapperChild = new ObjectMapperChild();
Unirest.setObjectMapper(objMapperChild);

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

В Java 1.8 с введением функциональных интерфейсов (интерфейсы только с одним методом) вы можете объявлять такие анонимные классы с использованием лямбда-выражений. Например, когда вы хотите отфильтровать список:

(Person p) -> p.getGender() == Person.Sex.MALE

такой же как

 new CheckPerson() {
     public boolean test(Person p) {
         return p.getGender() == Person.Sex.MALE;
     }
 }

когда

interface CheckPerson {
    boolean test(Person p);
}

Вы можете найти больше о лямбдах здесь - https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html.

Другие вопросы по тегам