简体   繁体   中英

why default method not recognized as property(getter/setter)?

Interface:

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

A Class implement it:

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

When initialized, I can call the method get Y & set Y , and get the right return. But I cannot use it in JSP( EL ), like ${instance_of_class_a.y} . And the property Y is not list in IDEA's variables list(Debug Mode).

If I do add the getY & setY explicitly in class A, everything is ok. Why? I think default method is like a compiler sugar.

Sorry for my poor english and the mistakes in the code, I've correct it.

The question is a bit ill written here, so maybe something went wrong. Especially add @Override for typos.

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

In general for getters/setters Class.getMethods is used.

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

I think I've got the answer.

BeanELResover using java.beans.Introspector to 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;
    }

The constructor of Introspector call a method "findExplicitBeanInfo" to getDeclaredMethods of current class. Then do it with its superClass until Object or stopClass. The method of interfaces will not be loaded here.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM