如何验证(泛型(泛型参数))?

2023-12-03

背景(我们真的不需要担心)

这是一个源自于的问题构建具有继承性的通用树。我将这个问题作为一个单独的问题来打开,因为这不仅与树问题有关。这更多的是一个通用和类问题。

Question

为了更好地用代码来说明,我们有一个Tree类,一个SubTree类,以及一个WrongSubTree class:

class Tree<TREE extends Tree<?,?>, DATA> {
}
class SubTree<STREE extends SubTree<?,?>, DATA> extends Tree<STREE, DATA> {
}
class WrongSubTree<WSTREE extends Tree<?,?>, DATA> extends Tree<WSTREE, DATA> {
}

在创建对象时,我们想检查泛型参数是否等于对象本身的类:

Tree<Tree<?,?>, String> tree01 = new Tree<Tree<?,?>, String>();                 // equals : OK
Tree<SubTree<?,?>, String> tree02 = new Tree<SubTree<?,?>, String>();           // (!) not equals
SubTree<SubTree<?,?>, String> tree03 = new SubTree<SubTree<?,?>, String>();     // equals : OK
WrongSubTree<Tree<?,?>, String> tree04 = new WrongSubTree<Tree<?,?>, String>(); // (!) not equals

(请注意,上面的 4 行目前没有编译错误,也没有运行时异常。)

My trial

为此,我们尝试添加一个Class<>构造函数中的参数:

class Tree<TREE extends Tree<?,?>, DATA> {
    public Tree(Class<TREE> clazz) {
        System.out.println(this.getClass());
        System.out.println(clazz);
        System.out.println();
        if (this.getClass() != clazz)
            throw new RuntimeException();
    }
}
class SubTree<STREE extends SubTree<?,?>, DATA> extends Tree<STREE, DATA> {
    public SubTree(Class<STREE> clazz) {
        super(clazz);
    }
}
class WrongSubTree<WSTREE extends Tree<?,?>, DATA> extends Tree<WSTREE, DATA> {
    public WrongSubTree(Class<WSTREE> clazz) {
        super(clazz);
    }
}

(以上类定义是有效的java代码。)

Problem

但我不知道如何调用该构造函数:

Tree<Tree<?,?>, String> tree01a = new Tree<Tree<?,?>, String>(Tree.class);
// The constructor Tree<Tree<?,?>,String>(Class<Tree>) is undefined

Tree<Tree<?,?>, String> tree01b = new Tree<Tree<?,?>, String>(Tree<?,?>.class);
// Syntax error, insert "Dimensions" to complete ArrayType

上面两行都会导致编译错误。

我想这是因为构造函数public Tree(Class<TREE> clazz) {}正在期待Class<Tree<?,?>>, 但不是Class<Tree>。然而,我们不能做Tree<?,?>.class.

原因是我试图将课程更改为:

class Tree<TREE extends Tree<?,?>, DATA> {
    public Tree(Class<Tree> clazz) {            // changed
        System.out.println(this.getClass());
        System.out.println(clazz);
        System.out.println();
        if (this.getClass() != clazz)
            throw new RuntimeException();
    }
}
Tree<Tree<?,?>, String> tree01a = new Tree<Tree<?,?>, String>(Tree.class);

没有编译错误。

但是,以下内容会导致相同的编译错误:

class Tree<TREE extends Tree<?,?>, DATA> {
    public Tree(Class<Tree<?,?>> clazz) {       // changed
        System.out.println(this.getClass());
        System.out.println(clazz);
        System.out.println();
        if (this.getClass() != clazz)
            throw new RuntimeException();
    }
}
Tree<Tree<?,?>, String> tree01a = new Tree<Tree<?,?>, String>(Tree.class);
// The constructor Tree<Tree<?,?>,String>(Class<Tree>) is undefined

Edit #1

基于我的评论下面,我尝试了这个。希望能够给大家带来一些启发。

static class SimpleClass<T> {
    private SimpleClass(Object dummy) {
        // dummy constructor, avoid recursive call of the default constructor
    }
    SimpleClass() {
        SimpleClass<T> myself = new SimpleClass<T>(new Object()) {};
        System.out.println(((ParameterizedType) myself.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
        // prints "T"

        TypeReference<SimpleClass<T>> typeRef = new TypeReference<SimpleClass<T>>() {};
        System.out.println(typeRef.getType());
        // prints "Main.Main$SimpleClass<T>"
    }
    void func() {
        SimpleClass<T> myself = new SimpleClass<T>(new Object()) {};
        System.out.println(((ParameterizedType) myself.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
        // prints "T"

        TypeReference<SimpleClass<T>> typeRef = new TypeReference<SimpleClass<T>>() {};
        System.out.println(typeRef.getType());
        // prints "Main.Main$SimpleClass<T>"
    }
}

public static void main(String[] args) {
    SimpleClass<String> simpleObj = new SimpleClass<String>();
    simpleObj.func();

    SimpleClass<String> outsideSimpleClass = new SimpleClass<String>(){};
    System.out.println(((ParameterizedType) outsideSimpleClass.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
    // prints "class java.lang.String"
}

注意我们仍然cannot获取“java.lang.String类”inside SimpleClass.

更重要的是,如果我们使用类型参数<T>实例化一个对象另一个班级,我们仍然无法从中获取类型参数:

static class AnotherClass<T> {
    private AnotherClass(Object dummy) {}
}
static class SimpleClass<T> {
    SimpleClass() {
        AnotherClass<T> another = new AnotherClass<T>(new Object()) {};
        System.out.println(((ParameterizedType) another.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
        // prints "T"

        TypeReference<AnotherClass<T>> anotherTypeRef = new TypeReference<AnotherClass<T>>() {};
        System.out.println(anotherTypeRef.getType());
        // prints "Main.Main$AnotherClass<T>"
    }
    void func() {
        AnotherClass<T> another = new AnotherClass<T>(new Object()) {};
        System.out.println(((ParameterizedType) another.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
        // prints "T"

        TypeReference<AnotherClass<T>> anotherTypeRef = new TypeReference<AnotherClass<T>>() {};
        System.out.println(anotherTypeRef.getType());
        // prints "Main.Main$AnotherClass<T>"
    }
}

请注意,这意味着类型参数AnotherClass不能透露于SimpleClass, 这是课堂之外的一个地方!

据我了解,我们只能使用匿名子类 &getGenericSuperclass()在它实际上已经知道答案的地方进行欺骗。比如在main(),这里是地方class java.lang.String实际上被定义为类型参数。

(IMO,如果这个技巧的能力受到如此限制,那么它根本就没有什么用处。)


查看文字工具(我创作的)为此。例子:

List<String> stringList = new ArrayList<String>() {};
Class<?> stringType = TypeResolver.resolveRawArgument(List.class, stringList.getClass());
assert stringType == String.class;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何验证(泛型(泛型参数))? 的相关文章

  • “源兼容性”和“目标兼容性”有什么区别?

    之间有什么关系 区别sourceCompatibility and targetCompatibility 当它们设置为不同的值时会发生什么 根据工具链和兼容性 https docs gradle org current userguide
  • 连接外部 Accumulo 实例和 java

    我正在尝试使用 Accumulo 连接到虚拟机 问题是 我无法将其连接到 Java 中 我可以看到 Apache 抛出的网页 但我无法让它与代码一起工作 我认为这是缺乏知识的问题而不是真正的问题 但我找不到这方面的文档 所有示例都使用 lo
  • java程序有多少种结束方式?

    我知道使用 System exit 0 可以结束一个java程序 例如 如果我有一个JFrame窗口 它会关闭并结束程序 但我想知道还有多少其他方法 可以关闭它并结束程序 包括发生错误时 程序会被关闭 JFrame也会被关闭吗 添加到其他答
  • 使用 proguard 混淆文件名

    我正在使用 proguard 和 Android Studio 混淆我的 apk 当我反编译我的apk时 我可以看到很多文件 例如aaa java aab java ETC 但我项目中的所有文件都有原始名称 有没有办法混淆我的项目的文件名
  • 在不支持 CAS 操作的处理器上进行 CompareAndSet

    今天 我在一次采访中被问到下一个问题 如果您在具有不支持 CAS 操作的处理器的机器上调用 AtomicLong 的compareAndSet 方法 会发生什么情况 您能否帮我解决这个问题 并在可能的情况下提供一些全面描述的链接 From
  • 我们可以有条件地声明 spring bean 吗?

    有没有一种方法可以有条件地声明 Spring bean 例如
  • 什么是内部类的合成反向引用

    我正在寻找应用程序中的内存泄漏 我正在使用的探查器告诉我寻找这些类型的引用 但我不知道我在寻找什么 有人可以解释一下吗 Thanks Elliott 您可以对 OUTER 类进行合成反向引用 但不能对内部类实例进行合成 e g class
  • 自定义列表字段点击事件

    我正在编写一个应用程序 其中我创建了用于显示列表视图的自定义列表字段 我的 CustomListField 包含连续的一个图像和文本 我正在通过单击列表字段行获取字段更改侦听器 但我也想将字段更改侦听器放在图像上 谁能告诉我我该怎么做 这是
  • 使用 OkHttp 下载损坏的文件

    我编写的下载文件的方法总是会产生损坏的文件 public static String okDownloadToFileSync final String link final String fileName final boolean te
  • 如何使用 Java Apache POI 隐藏 Excel 工作表中以下未使用的行?

    我正在使用数据库中的数据填充模板 Excel 工作表 for Map
  • getCurrentSession 在网络中休眠

    我正在使用 hibernate 和 jsp servlet 编写一个基于 Web 的应用程序 我读过有关sessionFactory getCurrentSession and sessionFactory openSession方法 我知
  • 2^31 次方的 Java 指数错误 [重复]

    这个问题在这里已经有答案了 我正在编写一个java程序来输出2的指数幂 顺便说一句 我不能使用Math pow 但是在 2 31 和 2 32 处我得到了其他东西 另外 我不打算接受负整数 My code class PrintPowers
  • 类更改(例如字段添加或删除)是否保持 Serialized 的向后兼容性?

    我有一个关于 Java 序列化的问题 在这种情况下 您可能需要修改可序列化类并保持向后兼容性 我有丰富的 C 经验 所以请允许我将 Java 与 NET 进行比较 在我的Java场景中 我需要使用Java的运行时序列化机制序列化一个对象 并
  • Android - 存储对ApplicationContext的引用

    我有一个静态 Preferences 类 其中包含一些应用程序首选项和类似的内容 可以在那里存储对 ApplicationContext 的引用吗 我需要该引用 以便我可以在不继承 Activity 的类中获取缓存文件夹和类似内容 你使用的
  • Joshua Bloch 的构建器设计模式有何改进?

    早在 2007 年 我就读过一篇关于 Joshua Blochs 所采用的 构建器模式 的文章 以及如何修改它以改善构造函数和 setter 的过度使用 特别是当对象具有大量属性 其中大部分属性是可选的 时 本文对此设计模式进行了简要总结
  • 如何使用 Jersey 将嵌套列表封送为 JSON?我得到一个空数组或一个包含数组的单元素字典数组

    我正在开发一个使用 Jersey 将对象转换为 JSON 的项目 我希望能够写出嵌套列表 如下所示 data one two three a b c 我想要转换的对象首先将数据表示为 gt gt 我认为 Jersey 会做正确的事情 以上输
  • Tomcat 6 未从 WEB-INF/lib 加载 jar

    我正在尝试找出我的 tomcat 环境中的配置问题 我们的生产服务器正在运行 tomcat 安装并从共享 NFS 挂载读取战争 然而 当我尝试使用独立的盒子 及其配置 进行同样的战争时 我收到下面发布的错误 有趣的是 如果我将 WEB IN
  • Lombok 不适用于 Eclipse Neon

    我下载了lombok jar lombok 1 16 14 jar 并将其放入我的下载中 然后我点击这个 jar 执行正确地识别了我的 MacOS 上的 Eclipse 实例 然后我选择了我想要的实例 Lombok也在pom xml中指定
  • 用于请求带有临时缓存的远程 Observable 的 RxJava 模式

    用例是这样的 我想暂时缓存最新发出的昂贵的Observable响应 但在它过期后 返回到昂贵的源Observable并再次缓存它 等等 一个非常基本的网络缓存场景 但我真的很难让它工作 private Observable
  • GAE 无法部署到 App Engine

    我正在尝试从 Eclipse 发布 Web 应用程序 我在 GAE 上创建了四个项目 可以通过登录我的帐户并查看控制台来查看它们 我已经改变了appengine web xml到项目的应用程序 ID 如果我将其更改为 GAE 上第一个创建的

随机推荐

  • Alexa 是否/可以替换其为链接用户生成的 UserId?

    我们有一个利用 Alexa 技能的应用程序 其中包含用户详细信息的帐户链接 根据 Alexa 的帐户关联 文档 我们的技能是为帐户链接设置的 帐户链接又引用第三方 或者可能是内部 身份管理系统 IMS 进行用户身份验证 我们的应用程序 以及
  • R:当列数为素数时分割数据框

    我有一个data frame有 131 列 我需要将其分成大约 10 到 15 个变量的组 即按列拆分 而不是按行拆分 显然 由于 131 是素数 因此并非所有新数据帧的长度都可以相同 我在帖子中寻找答案 如何在R中将数据切成偶数块 在 R
  • 带步骤选项的 math.random 函数? [关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 一个自定义函数 它将返回一个随机数 并带有可用的步骤选项 如for环形 例子 for i 1 10 2 do print i end 你的意思是这样吗 function randomW
  • Spring Boot 与 Intellij IDE 的热插拔

    我有一个 Spring Boot 应用程序在 Intellij IDE 上运行良好 即我启动了具有委托给 SpringApplication run 的 main 方法的 Application 类 除了热插拔之外 一切都很好 当我更改源时
  • 为什么两种情况下的输出不同?

    即使变量已被覆盖 为什么在以下情况下输出不同 public class A int a 500 void get System out println a is this a public class B extends A int a 1
  • 强制 cpp_dec_float 向下舍入

    我在用 str n std ios base scientific 打印ccp dec floats 我注意到它四舍五入了 我在用cpp dec float对于会计 所以我需要向下舍入 如何才能做到这一点 它没有四舍五入 事实上 它是银行家
  • 带 if 语句的 auto 函数不会返回值

    我做了一个模板和一个auto比较 2 个值并返回最小的值的函数 这是我的代码 include
  • 使用 3d 数据和参数在 Scipy 中进行曲线拟合

    我正在努力在 scipy 中拟合 3d 分布函数 我有一个 numpy 数组 其中包含 x 和 y 仓中的计数 我试图将其拟合到相当复杂的 3 维分布函数中 该数据适合 26 个参数 这些参数描述了其两个组成群体的形状 我在这里了解到 当我
  • 如何绘制簇内簇内平方和图?

    我有一个 R 的聚类图 同时我想用 wss 图优化聚类的 肘部准则 但我不知道如何为给定的聚类绘制 wss 图 有人会帮助我吗 这是我的数据 Friendly lt c 0 467 0 175 0 004 0 025 0 083 0 004
  • 当我尝试使用异常时,为什么我的代码在 Qt Creator 中使用 -fno-exceptions 进行编译?

    在项目 pro 文件中我指定了 QMAKE CXXFLAGS fno exceptions 但我可以在我的应用程序中抛出异常 对此有什么想法吗 示例 这不应该起作用 但它起作用 include
  • 如何使用准备好的语句制作适当的 mysqli 扩展类?

    我正在尝试扩展 mysqli 类来创建一个帮助器类 该类将抽象出一些复杂性 我想要完成的主要事情之一是利用准备好的语句 我真的不知道从哪里开始 或者如何在一堂课中正确处理输入和输出 另一个问题是我在使用准备好的语句时无法将数据作为数组输出
  • 用表单搜索my​​sqli表并显示结果

    我正在搜索一个表格 其中的结果可能来自 3 个选项 cata catb 或 catc 中的任何一个 然后显示结果 但是我的错误警告不断弹出并且无法显示结果 我被困住了
  • 字符串到 int 的转换和字符串操作 MIPS

    对于我的家庭作业 我需要使用 MIPS 获取前面带有任意字母后跟数字 例如 x123 的输入 然后将数字加 5 然后打印出最终数字 从示例中输出将是 128 data entmsg asciiz Enter a string n ui1 s
  • 如何使用 JSch 和 SFTP 协议检查读取权限?

    我知道有getPermissions 方法 但不知道怎么用 如何使用 JSch 检查用户是否可以读取文件 首先 您通常应该问一个功能性问题 您想要实现什么 以获得有用的答案 您要求实现 技术细节 因此我可能无用的技术答案 SftpATTRS
  • 在 VC++ 中使用 openCV 进行网络摄像机视频流传输

    我从来没有编写过 VC 应用程序 现在我被分配了一个捕获 IP 摄像机并将其保存为硬盘上的文件的任务 我过去两天一直在冲浪 但找不到任何合适的链接或代码 我在网上找到的示例代码捕获网络摄像头 但与使用凭据读取 rtsp 协议上的视频流无关
  • 使用 Dart 下载 PNG 文件(二进制文件)并显示它不起作用

    我有一个 Rest API 我调用它来检索要在我的页面上显示的 PNG 图像 My Code void getProfilePicture var pic id request new HttpRequest request respons
  • PayPal - 使用 php 加密多项目自定义购物车动态结账按钮

    我创建了一个网站 要求我构建一个自定义购物篮以满足业务需求 这一切工作正常 上周我一直在尝试制作一个加密的 使用 PayPal 结帐 按钮 首先我尝试了这个 www x com message 174366 没有超链接 因为我是新用户 抱歉
  • 了解子文件夹中的 Web.config 层次结构

    在我的 Visual Studio Web 项目中是Web config在根 That Web config文件定义了一个网络User and Password用于基本网络身份验证
  • 覆盖特定的第三方 Woocommerce 插件模板

    我正在使用基于 Woocommerce 的插件 名为混合搭配产品 这个插件位于里面 plugins woocommerce mix and match products 此文件夹包含另一个模板文件夹 按照惯例 我复制了 模板将 文件夹放入我
  • 如何验证(泛型(泛型参数))?

    背景 我们真的不需要担心 这是一个源自于的问题构建具有继承性的通用树 我将这个问题作为一个单独的问题来打开 因为这不仅与树问题有关 这更多的是一个通用和类问题 Question 为了更好地用代码来说明 我们有一个Tree类 一个SubTre