Определение метода в методе [дубликат]

Эти символы «u», добавленные к объекту, означают, что объект закодирован в «unicode».

Если вы хотите удалить эти «u» символы из своего объекта, вы можете сделать это:

import json, ast
jdata = ast.literal_eval(json.dumps(jdata)) # Removing uni-code chars

Давайте проверим из оболочки python

>>> import json, ast
>>> jdata = [{u'i': u'imap.gmail.com', u'p': u'aaaa'}, {u'i': u'333imap.com', u'p': u'bbbb'}]
>>> jdata = ast.literal_eval(json.dumps(jdata))
>>> jdata
[{'i': 'imap.gmail.com', 'p': 'aaaa'}, {'i': '333imap.com', 'p': 'bbbb'}]
274
задан ROMANIA_engineer 4 February 2016 в 10:53
поделиться

18 ответов

Под «анонимным классом», я полагаю, вы имеете в виду анонимный внутренний класс .

Анонимный внутренний класс может пригодиться при создании экземпляра объекта с определенным " extras ", например методы перегрузки, без фактического подкласса класса.

Я использую его как ярлык для присоединения слушателя событий:

button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // do something
    }
});

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

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

339
ответ дан EpicPandaForce 20 August 2018 в 22:21
поделиться
  • 1
    Или вы можете реорганизовать дубликаты анонимных внутренних классов в один метод с анонимным внутренним классом (и, возможно, с каким-либо другим дублированным кодом). – Tom Hawtin - tackline 14 December 2008 в 18:13
  • 2
    Отличный ответ, но быстрый вопрос. Означает ли это, что Java может жить без анонимных внутренних классов, и они похожи на дополнительный вариант выбора? – realPK 23 February 2014 в 22:37
  • 3
    Очень хорошо объяснил, даже жестко я предлагаю, чтобы кто-нибудь читал это, чтобы посмотреть вверх и посмотреть, что могут сделать java 8 и лямбда-выражения, чтобы сделать кодирование более быстрым и читаемым. – Pievis 27 March 2014 в 22:26
  • 4
    @ user2190639 Точно, не могу попросить лучше с Lambda в Java8 – bonCodigo 6 May 2014 в 00:39
  • 5
    почему вы сказали overloading methods, а не overriding methods? – Tarun 14 September 2016 в 12:48

Анонимные внутренние классы фактически закрывают, поэтому их можно использовать для эмуляции лямбда-выражений или «делегатов». Например, возьмите этот интерфейс:

public interface F<A, B> {
   B f(A a);
}

Вы можете использовать это анонимно, чтобы создать функцию первого класса в Java. Допустим, у вас есть следующий метод, который возвращает первое число, большее, чем i в данном списке, или i, если число не больше:

public static int larger(final List<Integer> ns, final int i) {
  for (Integer n : ns)
     if (n > i)
        return n;
  return i;
}

И у вас есть другой метод, который возвращает первый номер меньшего размера чем i в данном списке, или i, если число меньше:

public static int smaller(final List<Integer> ns, final int i) {
   for (Integer n : ns)
      if (n < i)
         return n;
   return i;
}

Эти методы почти идентичны. Используя первоклассный тип функции F, мы можем переписать их в один метод следующим образом:

public static <T> T firstMatch(final List<T> ts, final F<T, Boolean> f, T z) {
   for (T t : ts)
      if (f.f(t))
         return t;
   return z;
}

Вы можете использовать анонимный класс для использования метода firstMatch:

F<Integer, Boolean> greaterThanTen = new F<Integer, Boolean> {
   Boolean f(final Integer n) {
      return n > 10;
   }
};
int moreThanMyFingersCanCount = firstMatch(xs, greaterThanTen, x);

Это действительно надуманный пример, но его легко увидеть, что возможность передавать функции вокруг, как если бы они были значениями, является довольно полезной функцией. См. «Может ли ваш язык программирования делать это» самим Джоэлем.

Хорошая библиотека для программирования Java в этом стиле: Функциональная Java.

69
ответ дан 3 revs, 2 users 97% 20 August 2018 в 22:21
поделиться
  • 1
    К сожалению, многословие выполнения функционального программирования в java, IMHO, перевешивает его выигрыш - одна из ярких точек функционального программирования заключается в том, что он имеет тенденцию уменьшать размер кода и упрощает чтение и изменение. Но функциональная java, похоже, не делает этого вообще. – Chii 10 December 2008 в 09:49
  • 2
    Вся понятность функционального программирования, с ясностью Java! – Adam Jaskiewicz 10 December 2008 в 14:37
  • 3
    По моему опыту, функциональный стиль в Java оплачивается с многословием вверх, но он дает краткость в долгосрочной перспективе. Например, myList.map (f) значительно меньше подробностей, чем соответствующий для цикла. – Apocalisp 10 December 2008 в 18:46
  • 4
    Scala , язык программирования функционального программирования, предположительно хорошо работает внутри JVM и может быть вариантом для сценариев функционального программирования. – Darrell Teague 4 March 2013 в 19:57

Еще одно преимущество: поскольку вы знаете, что Java не поддерживает множественное наследование, поэтому, если вы используете класс типа «Thread» как анонимный класс, тогда класс по-прежнему имеет одно пространство, оставшееся для расширения любого другого класса.

0
ответ дан Arun Raaj 20 August 2018 в 22:21
поделиться

Анонимный внутренний класс используется для создания объекта, который никогда не будет ссылаться снова. Он не имеет имени и объявляется и создается в том же самом заявлении. Это используется там, где вы обычно используете переменную объекта. Вы заменяете переменную ключевым словом new, вызовом конструктора и определением класса внутри { и }.

При написании Threaded Program в Java это обычно выглядит так:

ThreadClass task = new ThreadClass();
Thread runner = new Thread(task);
runner.start();

Используемый здесь ThreadClass будет определяться пользователем. Этот класс будет реализовывать интерфейс Runnable, необходимый для создания потоков. В ThreadClass также необходимо реализовать метод run() (только метод из Runnable). Понятно, что избавление от ThreadClass было бы более эффективным, и именно поэтому существуют Анонимные Внутренние Классы.

Посмотрите на следующий код

Thread runner = new Thread(new Runnable() {
    public void run() {
        //Thread does it's work here
    }
});
runner.start();

Этот код заменяет ссылку сделанный в task в самом верхнем примере. Вместо того, чтобы иметь отдельный класс, Анонимный Внутренний Класс внутри конструктора Thread() возвращает неназванный объект, который реализует интерфейс Runnable и переопределяет метод run(). Метод run() будет включать в себя заявления внутри, которые выполняют работу, требуемую потоком.

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

Ссылки: Sams Teach Yourself Java в 21 день Седьмое издание

0
ответ дан Avishka Ariyaratne 20 August 2018 в 22:21
поделиться

Одно из основных применений анонимных классов в завершении класса, которое называется guardizer . В Java-мире использование методов finalize следует избегать, пока вы им не понадобятся. Вы должны помнить, что когда вы переопределяете метод finalize для подклассов, вы всегда должны вызывать super.finalize(), потому что метод finalize суперкласса не будет вызываться автоматически, и у вас могут возникнуть проблемы с утечками памяти.

, поэтому, учитывая упомянутый выше факт, вы можете просто использовать анонимные классы, например:

public class HeavyClass{
    private final Object finalizerGuardian = new Object() {
        @Override
        protected void finalize() throws Throwable{
            //Finalize outer HeavyClass object
        }
    };
}

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

1
ответ дан Hazhir 20 August 2018 в 22:21
поделиться

Внутренний класс связан с экземпляром внешнего класса и есть два специальных вида: Локальный класс и Анонимный класс . Анонимный класс позволяет нам объявлять и создавать экземпляр класса одновременно, поэтому делает код кратким. Мы используем их, когда нам нужен локальный класс только один раз, поскольку у них нет имени.

Рассмотрим пример из doc , где мы имеем класс Person:

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}

, и у нас есть способ печати элементов, которые соответствуют критериям поиска:

public static void printPersons(
    List<Person> roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}

, где CheckPerson - это интерфейс, такой как:

interface CheckPerson {
    boolean test(Person p);
}

Теперь мы можем использовать анонимный класс, который реализует этот интерфейс, чтобы указать критерии поиска как:

printPersons(
    roster,
    new CheckPerson() {
        public boolean test(Person p) {
            return p.getGender() == Person.Sex.MALE
                && p.getAge() >= 18
                && p.getAge() <= 25;
        }
    }
);

. Здесь интерфейс очень прост, и синтаксис анонимного класса кажется громоздким и непонятным.

В Java 8 введен термин функциональный интерфейс , который является интерфейсом только с одним абстрактным методом, поэтому можно сказать, CheckPerson является функциональным интерфейсом. Мы можем использовать выражение Lambda Expression , которое позволяет нам передать функцию как аргумент метода как:

printPersons(
                roster,
                (Person p) -> p.getGender() == Person.Sex.MALE
                        && p.getAge() >= 18
                        && p.getAge() <= 25
        );

Вместо стандартного функционального интерфейса Predicate мы можем использовать интерфейс CheckPerson, что дополнительно уменьшит требуемый код.

2
ответ дан i_am_zero 20 August 2018 в 22:21
поделиться

GuideLines для анонимного класса.

  1. Анонимный класс объявляется и инициализируется одновременно.
  2. Анонимный класс должен расширять или реализовывать только один класс или интерфейс соответственно
  3. Поскольку класс anonymouse не имеет имени, его можно использовать только один раз.

например:

button.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }
});
6
ответ дан Kumar Vivek Mitra 20 August 2018 в 22:21
поделиться
  • 1
    Что касается № 3: Не совсем верно. Вы можете получить несколько экземпляров анонимного класса с отражением, например. ref.getClass().newInstance(). – icza 11 July 2014 в 12:54
  • 2
    Правила не отвечают на вопрос. – user207421 9 August 2015 в 06:34

Да, анонимные внутренние классы определенно являются одним из преимуществ Java.

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

Но главное преимущество заключается в том, что внутренний код класса, который (по крайней мере должен быть) тесно связан с окружающим классом / методом / блоком, имеет конкретный контекст (окружающий класс, метод и блок). [/ д2]

4
ответ дан Lars A Frøyland 20 August 2018 в 22:21
поделиться
  • 1
    Доступ к окружающему классу очень важен! Я думаю, что это причина во многих случаях, когда используется анонимный класс, потому что ему нужны / используют непубличные атрибуты, методы и локальные переменные окружающего класса / метода, которые вперёд (если будет использоваться отдельный класс) должны были бы быть передан или опубликован. – icza 11 July 2014 в 13:06

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

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

Вот пример качания

myButton.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e) {
        // do stuff here...
    }
});

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

17
ответ дан madlep 20 August 2018 в 22:21
поделиться
  • 1
    Вы имели в виду сказать краткий? Если он будет подробным, обратный вызов будет оставаться отдельно, делая его немного большим и, таким образом, делая его многословным. Если вы скажете, что это все еще многословно, что тогда было бы кратким? – user3081519 12 February 2014 в 04:16
  • 2
    @ user3081519, что-то вроде myButton.addActionListener(e -> { /* do stuff here */}) или myButton.addActionListener(stuff) будет терпеливым. – Samuel Edwin Ward 20 May 2015 в 22:42
new Thread() {
        public void run() {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                System.out.println("Exception message: " + e.getMessage());
                System.out.println("Exception cause: " + e.getCause());
            }
        }
    }.start();

Это также один из примеров анонимного внутреннего типа с использованием thread

5
ответ дан realPK 20 August 2018 в 22:21
поделиться

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

1.) Для переопределения (подкласс), когда определение класса не используется, кроме текущего случая:

class A{
   public void methodA() {
      System.out.println("methodA");
    }
}
class B{
    A a = new A() {
     public void methodA() {
        System.out.println("anonymous methodA");
     }
   };
}

2 .) Для реализации интерфейса, когда реализация интерфейса требуется только для текущего случая:

interface interfaceA{
   public void methodA();
}
class B{
   interfaceA a = new interfaceA() {
     public void methodA() {
        System.out.println("anonymous methodA implementer");
     }
   };
}

3.) Аргумент Определенный Анонимный внутренний класс:

 interface Foo {
   void methodFoo();
 }
 class B{
  void do(Foo f) { }
}

class A{
   void methodA() {
     B b = new B();
     b.do(new Foo() {
       public void methodFoo() {
         System.out.println("methodFoo");
       } 
     });
   } 
 } 
43
ответ дан Sandeep Kumar 20 August 2018 в 22:21
поделиться
  • 1
    Отличный ответ, выглядит как 3.) - это шаблон, используемый для прослушивателей событий – xdl 25 April 2014 в 01:11
  • 2
    Большое вам спасибо за прекрасное описание. – pippi longstocking 22 February 2018 в 03:46

Лучший способ оптимизации кода. Кроме того, мы можем использовать для переопределения метод класса или интерфейса.

import java.util.Scanner;
abstract class AnonymousInner {
    abstract void sum();
}

class AnonymousInnerMain {
    public static void main(String []k){
        Scanner sn = new Scanner(System.in);
        System.out.println("Enter two vlaues");
            int a= Integer.parseInt(sn.nextLine());
            int b= Integer.parseInt(sn.nextLine()); 
        AnonymousInner ac = new AnonymousInner(){
            void sum(){
                int c= a+b;
                System.out.println("Sum of two number is: "+c);
            }
        };
        ac.sum();
    }

}
0
ответ дан Shivendra Pandey 20 August 2018 в 22:21
поделиться

Вы можете использовать анонимный класс

TreeSet treeSetObj = new TreeSet(new Comparator()
{
    public int compare(String i1,String i2)
    {
        return i2.compareTo(i1);
    }
});
1
ответ дан shuttle87 20 August 2018 в 22:21
поделиться

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

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

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

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

7
ответ дан Uri 20 August 2018 в 22:21
поделиться

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

2
ответ дан user1923551 20 August 2018 в 22:21
поделиться

Я иногда использую их в качестве синтаксического взлома для создания карты:

Map map = new HashMap() {{
   put("key", "value");
}};

vs

Map map = new HashMap();
map.put("key", "value");

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

43
ответ дан user207421 20 August 2018 в 22:21
поделиться
  • 1
    Чтобы быть ясным, первый набор фигурных скобок является анонимным внутренним классом (подклассификация HashMap). Второй набор фигурных скобок - это инициализатор экземпляра (а не статический), который затем устанавливает значения в вашем подклассе HashMap. +1 для упоминания об этом, -1 для того, чтобы не указывать его на noobs. ;-D – Spencer Kormos 12 December 2008 в 04:19
  • 2
    Подробнее о синтаксисе двойной привязки здесь . – Martin Andersson 18 February 2013 в 10:04
  • 3
    [Д0] blog.jooq.org/2014/12/08/… – starcorn 1 February 2016 в 23:25

Кажется, здесь никто не упоминается, но вы также можете использовать анонимный класс для хранения аргумента generic type (который обычно теряется из-за стирания типа) :

public abstract class TypeHolder<T> {
    private final Type type;

    public TypeReference() {
        // you may do do additional sanity checks here
        final Type superClass = getClass().getGenericSuperclass();
        this.type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
    }

    public final Type getType() {
        return this.type;
    }
}

Если вы экземпляр этого класса анонимным способом

TypeHolder<List<String>, Map<Ineger, Long>> holder = 
    new TypeHolder<List<String>, Map<Ineger, Long>>() {};

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

Использование

Это очень удобно для создания валидаторов / десериализаторов. Кроме того, вы можете создавать типичный тип с отражением (так что если вы когда-либо хотели сделать new T() в параметризованном типе - приветствуется!) [/ ​​G1].

Недостатки / ограничения

  1. Вы должны явно передать общий параметр. Несоблюдение этого правила приведет к потере параметров типа
  2. . Каждый экземпляр будет стоить вам дополнительного класса, который должен быть сгенерирован компилятором, что приводит к загрязнению кластера / jar bloating
3
ответ дан vsminkov 20 August 2018 в 22:21
поделиться
3
ответ дан vsminkov 31 October 2018 в 17:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: