了解匿名类

时间:2016-04-18 20:03:24

标签: java

我试图理解这段代码的实际含义。

  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);
    }
    

1 个答案:

答案 0 :(得分:2)

您的问题分为两部分:

  1. 什么是静态inializer?
  2. 什么是匿名课程?
  3. 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;
                        }    
                    }
                };
            }
        };