-3

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 getY & setY, 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.

brallow
  • 49
  • 3
  • because your class doesn't have any property named `y` – Jorj Oct 29 '18 at 09:02
  • 1
    Your code is wrong. How can you return `Integer` (`getX()`) in `getY()` which returns `String`? Also, `setX()` in interface has no parameter but your override has parameter. This code doesn't even compiles. – Jai Oct 29 '18 at 09:06
  • I've edit the code. I'm sure the original source code(is a little complex) is compiled successfully. And I can get the property X in EL(or any other properties except Y which is not explicitly declared in classA(just defined as default in someInt). – brallow Oct 29 '18 at 09:23

2 Answers2

1

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
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
0

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];
    }
}
brallow
  • 49
  • 3