RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 720871
Accepted
Direct
Direct
Asked:2020-09-20 20:17:49 +0000 UTC2020-09-20 20:17:49 +0000 UTC 2020-09-20 20:17:49 +0000 UTC

如何确定对象的“编译器”类型?

  • 772
public class GenericMethods {
    public <A,B,C> void f(A x,B y, C z) {
        System.out.println(x.getClass().getName());
        System.out.println(y.getClass().getName());
        System.out.println(Класс.вывести_то_что_видит_компилятор(y));
        System.out.println(z.getClass().getName());
    }

    public static void main(String[] args) {
        GenericMethods gm = new GenericMethods();
        gm.<String,Object,GenericMethods>f("Hello", 54, gm);
    }
}

问题:
是否有可能以某种方式强制 JVM 显示它在编译阶段正式拥有y的函数内的f()如果使用RTTI,那么我们会看到java.lang.Integer,但是我在泛型中强行指出要取变量所属java.lang.Object的参数化类型。也就是说,我不想看到真正的类型。我需要知道正式...Byy

java
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    default locale
    2020-09-20T21:25:23Z2020-09-20T21:25:23Z

    这是被禁止的。

    形式参数仅在编译时存在。编译器会删除有关它们的信息。在运行时可用的类型称为可具体化。

    Java 规范中描述了运行时可用类型的标准,泛型类型参数不可用:

    4.7. Reifiable Types
    由于某些类型信息在编译期间被删除,因此并非所有类型在运行时都可用。在运行时完全可用的类型称为可具体化类型。
    当且仅当满足以下条件之一时,类型才是可具体化的:
    - 它指的是非泛型类或接口类型声明。
    - 它是一种参数化类型,其中所有类型参数都是无界通配符(第 4.5.1 节)。
    - 它是原始类型(§4.8)。
    - 它是一种原始类型(§4.2)。
    - 它是一个数组类型(第 10.1 节),其元素类型是可具体化的。
    - 它是一种嵌套类型,其中,对于由“.”分隔的每个类型 T,T 本身都是可具体化的。
    ... 4.7。可物化类型
    因为 一些信息在编译时被删除,并非所有类型在运行时都可用。在运行时可用的是满足以下条件之一的类型:
    - 类型是未参数化的类或接口。
    - 一种参数化类型,其中所有类型参数都是不受限制的通配符。
    - 未成形的类型。
    - 原始类型。
    - 其元素类型在运行时可用的数组。
    - 嵌套类型,对于所有T点分隔类型,该类型T在运行时可用。

    其他类型被覆盖

    如果你真的想要:

    如果您想将类型信息存储为实验,您可以为类参数执行此操作。您可以通过为每个参数类型创建一个匿名类来强制编译器存储有关指定类型的信息。例如,如果您创建一个类:

    abstract class GenericClass<T> {
        private final T value;
        public GenericClass(T value) {
            this.value = value;
        }  
    
        /**
        * Пытается отловить значение типа, которое использовалось при компиляции.
        * Сработает только для параметризованных наследников
        */
        public Type getCompileTimeType() {
            final Type superclass = this.getClass().getGenericSuperclass();
            if(!(superclass instanceof ParameterizedType)) {
                throw new RuntimeException("С непараметризованными не получится");
            }
            final Type[] types = ((ParameterizedType) superclass).getActualTypeArguments();
            return types[0];
        }
    
        public Type getActualType() {
            return value.getClass();
        }
    }
    

    并创建一个继承自它的匿名类的对象:

    //анонимный класс, обратите внимание на {}
    GenericClass clazz = new GenericClass<Object>(5) {}
    

    ,然后该方法getCompileTimeType将返回Object,并且getActualType- Integer。

    这是因为编译器为匿名类创建了一个单独的后代,GenericClass相当于以下类:

    class ObjectClass extends GenericClass<Object>{
        public ObjectClass(Object value) {
            super(value);
        }
    }
    

    ,它允许您保存反射参数的类型GenericClass。但是,请记住,编译器将为每个参数类型(等)创建单独的类GenericClass<Integer>,GenericClass<Object>这会对性能产生不利影响。

    该机制适用于实验和研究编译器和泛型类型的操作。在实践中不值得使用它,因为。该机制极其不明显、效率低下和脆弱。

    链接:

    • 英文版类型擦除问题:Java generics - type erasure - when and what happens
    • 一篇关于从匿名类中提取参数类型的文章:Using TypeTokens to retrieve generic parameters
    • 5
  2. Nofate
    2020-09-20T20:35:49Z2020-09-20T20:35:49Z

    我需要学习正式的

    类型擦除不会让您识别它。对于运行时,它将无处不在Object。

    • 3

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5