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.