Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8和Bean信息内省器中接口中的默认方法_Java_Interface_Javabeans_Java 8_Propertydescriptor - Fatal编程技术网

Java 8和Bean信息内省器中接口中的默认方法

Java 8和Bean信息内省器中接口中的默认方法,java,interface,javabeans,java-8,propertydescriptor,Java,Interface,Javabeans,Java 8,Propertydescriptor,我对Interface和BeanInfo Introspector中的默认方法有点问题。 在这个例子中,有一个接口:interface public static interface Interface { default public String getLetter() { return "A"; } } 以及两个类别A和类别B: public static class ClassA implements Interface { } public stat

我对Interface和BeanInfo Introspector中的默认方法有点问题。 在这个例子中,有一个接口:interface

public static interface Interface {
    default public String getLetter() {
        return "A";
    }
}
以及两个类别A和类别B:

public static class ClassA implements Interface {
}

public static class ClassB implements Interface {
    public String getLetter() {
        return "B";
    }
}
在main方法中,应用程序从BeanInfo打印PropertyDescriptors:

public static String formatData(PropertyDescriptor[] pds) {
    return Arrays.asList(pds).stream()
            .map((pd) -> pd.getName()).collect(Collectors.joining(", "));

}

public static void main(String[] args) {


    try {
        System.out.println(
                formatData(Introspector.getBeanInfo(ClassA.class)
                        .getPropertyDescriptors()));
        System.out.println(
                formatData(Introspector.getBeanInfo(ClassB.class)
                        .getPropertyDescriptors()));
    } catch (IntrospectionException e) {
        e.printStackTrace();
    }

}
结果是:

class
class, letter

为什么默认方法“字母”在ClassA中不作为属性可见?这是bug还是特性?

这是因为您只在接口和类B上使用方法,而不是直接在类A上使用方法。然而,对我来说,这听起来像一个bug,因为我希望该属性会出现在列表中。我怀疑InProSector还没有赶上Java 8的功能。

这是因为您的方法只在接口和类B上,而不是直接在类A上。然而,对我来说,这听起来像一个bug,因为我希望该属性会出现在列表中。我怀疑InProSector还没有赶上Java 8的功能。

调试显示,该方法在
内省程序#getPublicDeclaredMethods()中被过滤掉了。

其中,
clz
是所讨论类的完全限定名


由于
ClassB
有此方法的自定义实现,因此它成功地通过了检查,而
ClassA
没有通过检查。

调试显示,此方法在
Introspector#getPublicDeclaredMethods()中被过滤掉:

其中,
clz
是所讨论类的完全限定名


由于
ClassB
有此方法的自定义实现,因此它成功地通过了检查,而
ClassA
没有。

我想,
Introspector
不会处理
接口
层次结构链,即使使用Java 8虚拟扩展方法(也称为defenders,默认方法)接口可以有一些类似于属性方法的东西。这里有一个相当简单的内省者声称它确实做到了:

这是否可以被认为是一个bug是一个灰色地带,以下是我这么认为的原因

显然,现在一个类可以从一个接口“继承”一个方法,该方法具有通常被认为是getter/setter/mutator的所有特性。但同时,这一切都违背了接口的目的——接口不可能提供任何可以被视为属性的东西,因为它是无状态和无行为的,它只是用来描述行为的。即使defender方法也基本上是静态的,除非它们访问具体实现的真实属性


另一方面,如果我们假设捍卫者是正式继承的(而不是提供默认实现,这在某种程度上是一个不明确的定义),那么它们应该导致在实现类中创建合成方法,这些方法属于该类,并且作为
PropertyDescriptor
查找的一部分进行遍历。很明显,事情不是这样的,否则整个事情都会起作用似乎defender方法在这里得到了某种特殊的处理。

我想,
内省者
不会处理
接口
层次结构链,即使使用Java 8虚拟扩展方法(也称为defender,默认方法)接口可能有某种类似于属性方法的东西。这里有一个相当简单的内省者声称它确实做到了:

这是否可以被认为是一个bug是一个灰色地带,以下是我这么认为的原因

显然,现在一个类可以从一个接口“继承”一个方法,该方法具有通常被认为是getter/setter/mutator的所有特性。但同时,这一切都违背了接口的目的——接口不可能提供任何可以被视为属性的东西,因为它是无状态和无行为的,它只是用来描述行为的。即使defender方法也基本上是静态的,除非它们访问具体实现的真实属性


另一方面,如果我们假设捍卫者是正式继承的(而不是提供默认实现,这在某种程度上是一个不明确的定义),那么它们应该导致在实现类中创建合成方法,这些方法属于该类,并且作为
PropertyDescriptor
查找的一部分进行遍历。很明显,事情不是这样的,否则整个事情都会起作用似乎defender方法在这里得到了某种特殊处理。

我认为这也是一个bug。 您可以为您的类使用专用的BeanInfo,并通过提供以下内容来解决此问题:

/* (non-Javadoc)
 * @see java.beans.SimpleBeanInfo#getAdditionalBeanInfo()
 */
@Override
public BeanInfo[] getAdditionalBeanInfo()
{
    Class<?> superclass = Interface.class;
    BeanInfo info = null;

    try
    {
        info = Introspector.getBeanInfo(superclass);
    }
    catch (IntrospectionException e)
    {
        //nothing to do
    }

    if (info != null)
        return new BeanInfo[] { info };

    return null;
}
/*(非Javadoc)
*@see java.beans.SimpleBeanInfo#getAdditionalBeanInfo()
*/
@凌驾
公共BeanInfo[]获取附加BeanInfo()
{
Class superclass=Interface.Class;
BeanInfo info=null;
尝试
{
info=Introspector.getBeanInfo(超类);
}
捕获(内省异常e)
{
//无事可做
}
如果(信息!=null)
返回新的BeanInfo[]{info};
返回null;
}

我也认为这是一个bug。 您可以为您的类使用专用的BeanInfo,并通过提供以下内容来解决此问题:

/* (non-Javadoc)
 * @see java.beans.SimpleBeanInfo#getAdditionalBeanInfo()
 */
@Override
public BeanInfo[] getAdditionalBeanInfo()
{
    Class<?> superclass = Interface.class;
    BeanInfo info = null;

    try
    {
        info = Introspector.getBeanInfo(superclass);
    }
    catch (IntrospectionException e)
    {
        //nothing to do
    }

    if (info != null)
        return new BeanInfo[] { info };

    return null;
}
/*(非Javadoc)
*@see java.beans.SimpleBeanInfo#getAdditionalBeanInfo()
*/
@凌驾
公共BeanInfo[]获取附加BeanInfo()
{
Class superclass=Interface.Class;
BeanInfo info=null;
尝试
{
info=Introspector.getBeanInfo(超类);
}
捕获(内省异常e)
{
//无事可做
}
如果(信息!=null)
返回新的BeanInfo[]{info};
返回null;
}

继承的方法如何?“这些不会也被过滤掉吗?”@SotiriosDelimanolis是的,它也被过滤掉了。但是在将近200行长的
processPropertyDescriptors()
方法的范围内,它被添加回:)继承的方法呢?“这些不会也被过滤掉吗?”@SotiriosDelimanolis是的,它也被过滤掉了。但是后来