为什么默认方法不能识别为属性(getter / setter)?

时间:2018-10-29 08:58:39

标签: java pojo default-method

接口:

public interface SomeInt{
   Integer getX();
   void setX(Integer value);
   default Integer getY(){
      return getX();
   }
   default void setY(Integer value){
       setX(value);
   }
}

一个Class实现它:

public class A implements SomeInt{
  private Integer x;
  public Integer getX(){
     return x;
  }
  public void setX(Integer value){
     x = value;
  }
}

初始化后,我可以调用方法get Y 并设置 Y ,并获得正确的回报。 但是我不能在JSP( EL )中使用它,例如${instance_of_class_a.y}。而且属性Y不在IDEA的变量列表(调试模式)中。

如果我确实在类A中显式添加了getY和setY,则一切正常。 为什么?我认为默认方法就像编译器糖一样。

对不起,我的英语不好,并且代码中的错误,我已经纠正了。

2 个答案:

答案 0 :(得分:1)

问题在这里写得有点不对劲,所以也许出了点问题。 尤其要添加@Override作为错字。

interface SomeInt {
    int getX();

    void setX(int x);

    default int getY() {
        return getX();
    }

    default void setY(int value) {
        setX(value);
    }
}

static class A implements SomeInt {
    private int x;

    @Override
    public int getX() {
        return x;
    }

    @Override
    public void setX(int value) {
        x = value;
    }
}

    System.out.println("Methods:");
    for (Method m : A.class.getMethods()) {
        System.out.printf("+ %s%n", m.getName());
    }
    for (Method m : A.class.getDeclaredMethods()) {
        System.out.printf("- %s%n", m.getName());
    }

通常使用吸尘器/设置器Class.getMethods

Methods:
+ setX
+ getX
...
+ setY
+ getY
- setX
- getX

答案 1 :(得分:0)

我想我已经找到答案了。

使用java.beans.Introspector进行BeanELResover以获得getBeanInfo(Properties)

public static BeanInfo getBeanInfo(Class<?> beanClass)
        throws IntrospectionException
    {
        if (!ReflectUtil.isPackageAccessible(beanClass)) {
            return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
        }
        ThreadGroupContext context = ThreadGroupContext.getContext();
        BeanInfo beanInfo;
        synchronized (declaredMethodCache) {
            beanInfo = context.getBeanInfo(beanClass);
        }
        if (beanInfo == null) {
            beanInfo = new Introspector(beanClass, null, USE_ALL_BEANINFO).getBeanInfo();
            synchronized (declaredMethodCache) {
                context.putBeanInfo(beanClass, beanInfo);
            }
        }
        return beanInfo;
    }

Introspector的构造函数将方法“ findExplicitBeanInfo”调用到当前类的getDeclaredMethods。然后使用其超类执行直到Object或stopClass。接口的方法不会在这里加载。

private Introspector(Class<?> beanClass, Class<?> stopClass, int flags)
                                        throws IntrospectionException {
    this.beanClass = beanClass;

    // Check stopClass is a superClass of startClass.
    if (stopClass != null) {
        boolean isSuper = false;
        for (Class<?> c = beanClass.getSuperclass(); c != null; c = c.getSuperclass()) {
            if (c == stopClass) {
                isSuper = true;
            }
        }
        if (!isSuper) {
            throw new IntrospectionException(stopClass.getName() + " not superclass of " +
                                    beanClass.getName());
        }
    }

    if (flags == USE_ALL_BEANINFO) {
        explicitBeanInfo = findExplicitBeanInfo(beanClass);
    }

    Class<?> superClass = beanClass.getSuperclass();
    if (superClass != stopClass) {
        int newFlags = flags;
        if (newFlags == IGNORE_IMMEDIATE_BEANINFO) {
            newFlags = USE_ALL_BEANINFO;
        }
        superBeanInfo = getBeanInfo(superClass, stopClass, newFlags);
    }
    if (explicitBeanInfo != null) {
        additionalBeanInfo = explicitBeanInfo.getAdditionalBeanInfo();
    }
    if (additionalBeanInfo == null) {
        additionalBeanInfo = new BeanInfo[0];
    }
}