Java, объявление метода внутри другого метода? - PullRequest
2 голосов
/ 16 февраля 2012

Я изучаю некоторый Java-код, написанный моим бывшим коллегой, и нашел то, что не могу правильно понять. Здесь у нас есть метод getGeneAvailableTaxonomies (), который, кажется, содержит вызов метода с собственным объявлением accept (). Это правда? Возможно ли это?

Вот часть кода: я не могу понять значение программы от FilenameFilter () до конца.

public List<Integer> getGeneAvailableTaxonomies() {
    List<Integer> availableTaxon = new ArrayList<Integer>();

    File dataDirectory = new File(_currentApplicationPath, String.format("Data"));
    FilenameFilter filter = new FilenameFilter() {
        public boolean accept(File dir, String name) {
            return name.startsWith("gene_") && name.endsWith("_info.info"); //get all info files...
        }
    };
    String[] children = dataDirectory.list(filter);

    for(String child:children) {
        availableTaxon.add(Integer.parseInt(child.substring(child.indexOf("_")+1, child.lastIndexOf("_"))));
    }

    return availableTaxon;
}

Ответы [ 7 ]

8 голосов
/ 16 февраля 2012

Часть кода, где вы видите определяемый метод accept(), называется анонимным классом.

FilenameFilter filter = new FilenameFilter() {
    public boolean accept(File dir, String name) {
        return name.startsWith("gene_") && name.endsWith("_info.info"); //get all info files...
    }
};

Здесь происходит создание нового класса - FilenameFilter. Они реализуют / переопределяют метод accept. Думайте об этом так, но в одном утверждении:

class MyFilenameFilter implements FilenameFilter {
    public boolean accept(File dir, String name) {
        return name.startsWith("gene_") && name.endsWith("_info.info"); 
    }
}

FilenameFilter filter = new MyFilenameFilter()
2 голосов
/ 16 февраля 2012

Это анонимный внутренний класс, то есть класс, который не имеет собственного имени и определяется как ad-hock вместе со своим экземпляром.

На самом деле имя этого класса - это имя вашего внешнего класса, за которым следуют $ и число (1, 2, 3 и т. Д.) В соответствии с порядковым номером вашего внутреннего класса.

1 голос
/ 16 февраля 2012

О, у меня нет университета. Но я узнал из Интернета.

Вы можете сделать это, это не «метод внутри метода». Он реализует интерфейс.

FilenameFilter

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

Отредактировано

Вы можете заметить точку с запятой после последней фигурной скобки new FilenameFilter() {.... Весь блок является выражением, поэтому его можно применять к полям / переменным ...

0 голосов
/ 16 февраля 2012

Вот что происходит. Синтаксис называется анонимный внутренний класс . new дает вам подсказку, что вы создаете новый класс, который наследуется от FilenameFilter - именно поэтому он может быть присвоен ссылке типа FilenameFilter - но этот класс реализует метод с именем accept, который перегружает метод FilenameFilter accept. У этого класса нет имени, видимого для остальной части программы (хотя некоторые компиляторы по крайней мере создадут файл класса в целевом каталоге), но его единственный экземпляр существует, пока filter остается в области действия.

Это своего рода почти лямбда, которая появилась в Java о Java 1.2 (я думаю.)

0 голосов
/ 16 февраля 2012

FilenameFilter - это интерфейс.Синтаксис new FilenameFilter(){...} здесь создает и создает анонимный класс, который реализует FilenameFilter с реализацией внутри.См. Файл , чтобы проверить, что делает dataDirectory.list().«Он возвращает массив строк с именами файлов и каталогов в каталоге, обозначенном этим абстрактным путем, которые удовлетворяют указанному фильтру.»

0 голосов
/ 16 февраля 2012

Это так называемые анонимные классы. Они описаны в JLS, но вы можете прочитать о них в «Java in Nutshell» или в некоторых других руководствах, чтобы лучше разобраться в этом.

0 голосов
/ 16 февраля 2012

Он создал свой собственный фильтр, чтобы решить, должен ли файл внутри dataDirectory быть включен в массив String или нет. Для этого ему пришлось реализовать собственную версию единственного интерфейса FilenameFilter, метод accept. Затем он применил этот фильтр к dataDirectory.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...