2016-04-18 2 views
1

Я пытаюсь понять, что на самом деле означает этот код.Понимание анонимных классов

  1. Почему весь этот код в статическом блоке?
  2. Что делает wrapMapper?

    static{ 
    
        //new XStream inside static block 
        xstream = new XStream(){ 
    
         // What is happening with the wrapMapper method? 
         protected MapperWrapper wrapMapper(MapperWrapper next) { 
    
          return new MapperWrapper(next) { 
    
           public boolean shouldSerializeMember(@SuppressWarnings("rawtypes") Class definedIn, String fieldName) { 
            if (definedIn != Object.class) { 
             return super.shouldSerializeMember(definedIn, fieldName); 
            } else { 
             return false; 
            }  
           } 
          }; 
         } 
        }; 
    
        xstream.processAnnotations(classA.class); 
        xstream.processAnnotations(classB.class); 
        xstream.processAnnotations(classC.class); 
    } 
    
+0

Блок 'static' инициализирует статические элементы в классе. Он выполняется только один раз. Объект 'xstream' инициализируется как анонимный класс и переопределяет' wrapMapper' в классе 'XStream' – Tgsmith61591

+0

Спасибо tgsmith. – Accribus

+0

Натан Хьюз, да, это, похоже, моя проблема. У меня не было слова, чтобы посмотреть. Теперь я знаю, как читать анонимные классы и почему. – Accribus

ответ

2

Есть две части вашего вопроса:

  1. Что такое статический inializer?
  2. Что такое анонимный класс?

Блок static инициализирует статические элементы в классе. Он выполняется только один раз. Вот простой пример того, как это может быть сделано в базовом классе:

public class A { 
    // we can initialize static members like this: 
    private static Object someObject = new Object(); 

    // this still needs to be initialized: 
    private static ArrayList<Integer> someList; 

    static { 
     // we can initialize it here: 
     someList = new ArrayList<Integer>(); 
     someList.add(1); 
    } 
} 

Это, как правило, используется для статических членов, которые являются коллекциями какого-то рода, и требуют более конфигурирования/установки, чем какой-либо другой объект (то есть, в наш пример, добавив в Сборник).

Anonymous classes, согласно документации:

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

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

public abstract class NamedObject { 
    abstract public String sayMyName(); 
} 

Любой неабстрактный подкласс этого объекта будет осуществлять sayMyName(). Мы можем сделать это двумя способами (в этом примере). Первый бы создать реальный подкласс явно:

public final class Heisenberg extends NamedObject { 
    @Override 
    public String sayMyName() { 
     return "Heisenberg"; 
    } 
} 

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

NamedObject anonymousObject = new NamedObject(){ 
    // we have to implement this method: 
    @Override 
    public String sayMyName() { 
     return "We are Anonymous"; 
    } 
} 

Теперь к первоначальному вопросу ... Переменная xstream инициализируются как анонимный класс. То, что вы видите с помощью метода wrapMapper, состоит в том, что анонимный класс переопределяет метод по умолчанию wrapMapper в классе XStream с его собственной функциональностью. Что особенно интересно в вашем примере, так это то, что анонимный класс создает еще еще один анонимный класс в своем методе wrapMapper, который вы можете увидеть в строке return new MapperWrapper, которая переопределяет метод shouldSerializeMember.

Личное мнение предупреждение: код, как это гораздо более разборчивыми при использовании @Override аннотацию явно указать, что вы переопределение супер метод.В таких случаях, когда нет подсветки синтаксиса IDE или контекста для этого метода, читателю намного проще расшифровать то, что происходит! Код можно было бы переписать следующим образом, и читатель сразу понял бы, что происходит:

xstream = new XStream(){ 

     @Override // we override the default behavior of this method 
     protected MapperWrapper wrapMapper(MapperWrapper next) { 
      return new MapperWrapper(next) { 

       @Override // we override the default behavior of this method 
       public boolean shouldSerializeMember(@SuppressWarnings("rawtypes") Class definedIn, String fieldName) { 
        if (definedIn != Object.class) { 
         return super.shouldSerializeMember(definedIn, fieldName); 
        } else { 
         return false; 
        }  
       } 
      }; 
     } 
    }; 
+0

Еще раз спасибо за помощь. Это действительно очищает его! – Accribus

+0

Конечно. Если это решит ваш вопрос, отметьте его как ответ! – Tgsmith61591

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