Подтвердить что ты не робот

Поддерживает ли Java внутренние/локальные/вспомогательные методы?

Это мой код.

public class SubFunction {
    private String drawTribleX(){
        return trible("X");
    }
    private String trible(String t){
        return t + t + t;
    }
    public static void main(String[] args){
        SubFunction o = new SubFunction();
        System.out.println(o.drawTribleX());
    }
}

Могу ли я сделать что-то вроде этого?

public class SubFunction {
    private String drawTribleX(){
        // *** move trible(t) inside drawTribleX() ***
        private String trible(String t){
            return t + t + t;
        }
        return trible("X");
    }
    public static void main(String[] args){
        SubFunction o = new SubFunction();
        System.out.println(o.drawTribleX());
    }
}

Спасибо.

4b9b3361

Ответ 1

Обновление 2014-02-09:

JDK 8 представил lambdas (анонимные функциональные выражения), которые позволяют вам решить это следующим образом:

Function<String, String> trible = s -> s+s+s;
System.out.println(trible.apply("X"));           // prints XXX

(JDK 7 и ниже)

Нет, Java не поддерживает "напрямую" вложенные методы. (Однако большинство функциональных языков, включая некоторые языки JVM, такие как Scala и Clojure!)

Просто для справки; Вы можете определить локальные классы (классы в методах), чтобы компилировать

class SubFunction {
    private String drawTribleX(){

        // *** move trible(t) inside drawTribleX() ***
        class Trible {
            private String trible(String t){
                return t + t + t;
            }
        }

        return new Trible().trible("X");
    }
    public static void main(String[] args){
        SubFunction o = new SubFunction();
        System.out.println(o.drawTribleX());
    }
}

Обратите внимание, что существуют ограничения для локальных классов

3.11.2. Ограничения на локальные классы

Локальные классы подчиняются следующим ограничениям:

  • Локальный класс отображается только внутри блока, который его определяет; он никогда не может использоваться вне этого блока.

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

  • Как и классы-члены, и по тем же причинам локальные классы не могут содержать статические поля, методы или классы. Единственное исключение - для констант, объявленных как статическими, так и окончательными.

  • Интерфейсы не могут быть определены локально.

  • Локальный класс, как класс-член, не может иметь то же имя, что и любой из его вмещающих классов.

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

Итак, как вы можете видеть, ваш первый вариант (без вложенных методов) предпочтительнее в этих ситуациях.

Ответ 2

Совершенно просто - нет. Вы не можете вложить метод в другой метод.

Если вы действительно хотите это сделать, вы можете определить классы в методах (как это ни странно, учитывая предыдущее ограничение), и поэтому можно обернуть ваши методы внутри класса во внешнем методе.

Однако это не очень идиоматично, и, как представляется, общая практика состоит в том, чтобы иметь список частных методов (в классе верхнего уровня), возможно, сгруппированных по назначению и блоков комментариев, демаркирующих группы.


Если вам удастся найти Scala, вы можете отложить методы до вашего сердечного контента...

Ответ 3

вы можете попробовать таким образом, который является анонимным внутренним классом.

public class SubFunction {
    private String drawTribleX() {
        // *** move trible(t) inside drawTribleX() ***
        Trible t = new Trible() {
            public String trible(String t) {
                return t + t + t;
            }
        };
        return t.trible("X");
    }

    public static void main(String[] args) {
        SubFunction o = new SubFunction();
        System.out.println(o.drawTribleX());
    }

    interface Trible {
        String trible(String t);
    }
}

Ответ 4

Вы можете использовать анонимный класс. Что-то вроде этого;

class SubFunction {

    public static void main(String[] args) {
        SubFunction o = new SubFunction();
        System.out.println(o.drawTribleX());
    }

    private String drawTribleX() {
        MyTrible trible = new MyTrible() {
            @Override
            public String doTrible(String t) {
                return t + t + t;
            }
        };

        return trible.doTrible("X");
    }

    private interface MyTrible {
        public String doTrible(String t);
    }
}

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