当前位置: 首页 > 知识库问答 >
问题:

在接口中强制转换类时奇怪的矛盾行为

陆仲渊
2023-03-14

我在一个项目中遇到了一些奇怪的行为,我举了一个例子:

class Main implements ClassGetter{
    public static void main(String[] args) {
        Main m = new Main();
        m.test();
    }

    public void test(){
        consumeClazz(this.getClass()); // error in editor
        consumeClazz((Class<? extends Clazz>) this.getClass()); // error in editor
        consumeClazz(getCastedClass()); // compiles and runs successfully
    }

    public void consumeClazz(Class<? extends Clazz> clazz){
        System.out.println(clazz.getSimpleName());
    }
}

interface ClassGetter{
    default Class<? extends Clazz> getCastedClass(){
        return (Class<? extends Clazz>) this.getClass(); // warning in editor
    }
}

class Clazz{}

重点是Main类中的test()方法和ClassGetter接口的getCastedClass()方法。test()方法中的前两行给出了编辑器中的错误,这些错误解释了类的工作方式

为什么最后一个示例有效,而前两个示例从未编译?


共有1个答案

宋嘉懿
2023-03-14

为什么这主要是非法的?

consumeClazz((Class<? extends Clazz>) this.getClass());

Main的实例不可能是Clazz的实例,因为它们是不相关的类,并且Java不支持多重继承。

为什么这在ClassGetter中是合法的?

return (Class<? extends Clazz>) this.getClass();

如果存在实现ClassGetter的Clazz子类,则ClassGetter的实例可能是Clazz的实例。因为这是可能的,这是合法的,但不安全。

为什么这主要是合法的?

consumeClazz(getCastedClass())

getCastedClass()声明为返回

为什么它能成功运行?

在运行时,泛型会被删除,而类

 类似资料:
  • 更新: 下面的编辑#2显示了此问题的临时解决方案,但提出了一个新问题。 我正在为我的视图开发一个使用Spring MVC和Thymeleaf的客户端。 我有两个用户,一个基本用户和一个管理员。当基本用户登录时,其个人信息将显示在主页上。当管理员登录时,他可以执行各种搜索操作以在后端数据库(MongoDB)中查找用户。他可以按州、市、用户名等查找。。。。 我得到这个错误:: 以管理员身份登录 就像我

  • 显然,这会导致编译错误,因为椅子与Cat无关: 那么,为什么只有在运行时,当我将Cat引用转换到不相关的接口家具时,才会出现异常,而编译器显然可以看出Cat没有实现家具?

  • 问题内容: 这可能是在某个地方被问到的,但我找不到。有人可以澄清为什么此代码可以编译并打印出来吗? 问题答案: 它被解析为: 所有和运算符都是一元或的。 在这种情况下,两次取反,因此将其打印为。

  • 我遇到了奇怪的问题时,铸造小数到双倍。 以下代码返回true: 但是,当我将其强制转换为双倍时,它返回false: 这是记录在案的行为吗?当我被迫将decimal转换为Double时,我如何避免它? Visual Studio的截图: 将Math.round铸造为双倍me,结果如下: null 不幸的是,我不能在较小的项目中重现这个问题。我想埃里克的回答解释了原因。

  • 和往常一样,我在浏览JDK8源代码时发现了非常有趣的代码: 问题是:如何可能是的实例?因为它们处于不同的层级。 我做了类似的代码片段来测试转换: