还是关于java泛型的问题:在静态方法中为什么不能引用类级别的类型参数?

问题描述

不要回答因为泛型类型参数需要声明对象时指定,而静态不需要对象就可以引用什么的。这个根本就不是原因。泛型和运行时系统没有一点关系。我解释一下在静态变量中不能使用类型参数的原因:因为静态变量为所有实例共享,如果可以使用,那么当使用不同的类型参数实例化对象时会导致编译器插入强制类型转换代码错误(1.5版泛型指南上有实例解释)。(换句话说泛型的实现机制擦拭法决定了不能再静态变量中使用类型参数)。但是这个问题并不影响静态方法中使用类型参数,而且静态方法可以是泛型方法,既然可以使泛型方法,那我引用类级别的类型参数又怎么了嘛,完全可以的啊。

解决方案

解决方案二:
回楼下的,我只能回答在静态变量中不能使用类型参数,不能回答在静态方法中为什么不能引用类级别的类型参数,我的回答只是抛砖引玉。以前这个问题我问过,很多人都给过我如上回答,其实都不正确。最近看了深入JVM和java1.5泛型指南中文版,又想起这个问题。只想大家帮忙从实现机制擦拭法的角度回答,而不是胡乱猜测。
解决方案三:
对象在实例化的时候才能知道具体是什么类型,而静态部分是JVM加载class是初始化的,而这个时候非静态部分是没有初始化的,所以JVM根本也不知道你的泛型到底是什么东西。
解决方案四:
是啊,正是JVM不知道泛型,所以才有这个疑问。静态方法可以使泛型方法,泛型方法的实现机制证明静态方法可以引用类级别的类型参数,但为什么不允许。
解决方案五:
引用2楼的回复:

对象在实例化的时候才能知道具体是什么类型,而静态部分是JVM加载class是初始化的,而这个时候非静态部分是没有初始化的,所以JVM根本也不知道你的泛型到底是什么东西。

你的第一句话和最后一句话矛盾。JVM不知道泛型是什么东西所以我使用静态方法引用泛型,也没问题。
解决方案六:
楼主,最近我也为这个问题烦恼,你的前半段解惑提醒了我;我想,应该是这样的吧:首先,在JVM加载Class的时候会将类中所有的常量,静态常量,静态方法写到内存的方法区内;其次,所有的常量,静态常量和静态方法在方法区内有且只有一份,并为所属类所创建的所有对象共享;那么用你的方式解释,问题来了,如果静态常量和静态方法中使用了类的类型变量,当程序猿使用不同的类型参数实例化对象时会导致编译器插入强制类型转换代码错误(1.5版泛型指南上有实例解释);例如,存在一个C泛型类,其静态方法中使用了类的类型变量,先后定义了A对象,B对象,那么如果A对象先把类的类型变量初始化为String,而B对象后把类的类型变量初始化为Integer。此时,静态方法中类的类型变量为Integer类型,而A对象又调用了这个静态方法。会出现你说的错误~类似于数据库中的读脏数据~以上你应该明白;那么关键在于:独立的泛型静态方法,在不考虑多线程的情况下,同一时间点,只会被初始化并调用一次,不会出现重叠初始化并错误调用,不会出现类似数据库中读脏数据的情况,所以不会出现强制类型转换的代码错误。

时间: 2024-10-31 09:28:52

还是关于java泛型的问题:在静态方法中为什么不能引用类级别的类型参数?的相关文章

Java 泛型详解

在日常的开发中,我们会看到别人的框架很多地方会使用到泛型,泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法.泛型的类型参数只能是类类型(包括自定义类),不能是简单类型.本篇博客我们就来详细解析一下泛型的知识. 泛型类定义及使用 使用泛型有什么好处呢?首先我们先看一个例子,假设我们有两个类,代码如下: #StringClass  public class Strin

通过Java泛型实现数组排序和搜索的通用方法

下面讨论的是数组的排序和搜索功能,而一个通用方法则是实现Comparable接口的方法,这个方法需要通过java泛型来实现.下面便逐步讲解为何,以及如何通过Java泛型实现此类的通用方法. 如何在java类中一些通用方法,特别是一些静态的工具方法? 比如,数组Arrays的sort.search等? 1. 整数数组的顺序收缩 public static int seqSearch(int[] arr, int first, int last, int target) { for (int i =

Java泛型详解_java

1. Why --引入泛型机制的原因     假如我们想要实现一个String数组,并且要求它可以动态改变大小,这时我们都会想到用ArrayList来聚合String对象.然而,过了一阵,我们想要实现一个大小可以改变的Date对象数组,这时我们当然希望能够重用之前写过的那个针对String对象的ArrayList实现.     在Java 5之前,ArrayList的实现大致如下: public class ArrayList { public Object get(int i) { ... }

java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题

参考:java核心技术 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首要前提是理解类型擦出(type erasure). Java中的泛型基本上都是在编译器这个层次来实现的.在生成的Java字节码中是不包含泛型中的类型信息的.使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉.这个过程就称为类型擦除. 如在代码中定义的List<object>和List<

java泛型学习(1)

java泛型(Generices Type)    --->概念:泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引入泛型的好处是安全简单. --->优点:(1)在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换

java泛型type体系整理

一直对jdk的ref使用比较模糊,早上花了点时间简单的整理了下,也帮助自己理解一下泛型的一些处理.   java中class,method,field的继承体系     java中所有对象的类型定义类Type   说明:    Type :  Type is the common superinterface for all types in the Java programming language. These include raw types, parameterized types, 

Eclipse V3.1中的Java泛型支持

Java 中的泛型 几乎从第一个版本开始,Java 技术的创立者们就已经开始讨论对该语言添加 泛型支持.C++ 通过标准模板库对泛型进行支持,但是由于缺少所有其他类(嵌 入在 Java 语言中的Object 类中)的一个统一父类,泛型的实现也受到阻碍.Java编程语言的泛型支持是其历史上最重大的语法变化.由于某些显而易见的原因,工具支持比其他 SDK 升级的步法要慢得多.尽管如此,现在 Eclipse V3.1 已经对这些语言的新特性有了出色的支持.本文重点介绍其中的一些新特 性. Java 5

java泛型异常,如何解决

问题描述 java泛型异常,如何解决 public static > AnyType[] mergesort(AnyType[] a,AnyType[] b) { int i=0; int j=0; int index=0; AnyType[] tmp=(AnyType[]) new Comparable[a.length+b.length]; while(i<a.length&&j<b.length){ if(a[i].compareTo(b[j])<0) { t

Java泛型详解

一 概念 1.1 为什么需要泛型?           当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,该对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型.因此,取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现"java.lang.ClassCastException"异常.使用泛型就可以解决此类问题. 1.2 什么是泛型?         泛型(Generic type 或者 generics)是对 Java 语