我知道java不应该支持通用参数,这些参数是原始类型,并且确实如下:
Vector<byte> test;
Run Code Online (Sandbox Code Playgroud)
将无法编译.
然而,我偶然在一个程序中执行了一点点手,我发现实际上可以用原始类型创建一个通用对象(技术如下所示)
此外,java错误地允许将此实例分配给类型的变量,而Vector<Byte>
当print语句显示时,byte.class和Byte.class是两个独立的野兽.因此,尝试对对象进行调用会导致意外和奇怪的行为/错误.
这是一个java bug吗?还是有些押韵或理由让这种疯狂?似乎即使java允许创建基本类型泛型的意外行为,它们也不应该被赋予包装类型的泛型,该类型与原语具有不同的类.
import java.util.Vector;
public class Test
{
//the trick here is that I am basing the return type of
//the vector off of the type that was given as the generic
//argument for the instance of the reflections type Class,
//however the the class given by byte.class yields a non-class
//type in the generic, and hence a Vector is created with a
//primitive type
public static <Type> Vector<Type> createTypedVector(Class<Type> type)
{
return new Vector<Type>(0,1);
}
public static void main(String ... args)
{
//these lines are to demonstrate that 'byte' and 'Byte'
//are 2 different class types
System.out.println(byte.class);
System.out.println(Byte.class);
//this is where I create an instance of type Vector<byte>
//and assign it to a variable of type Vector<Byte>
Vector<Byte> primitiveTypedGenericObject = createTypedVector(byte.class);
//this line causes unexpected exceptions to be thrown
//because primitiveTypedGenericObject is not actually type
//Vector<Byte>, but rather Vector<byte>
primitiveTypedGenericObject.set(0,(byte)0xFF);
}
}
Run Code Online (Sandbox Code Playgroud)
Jac*_*ack 19
这两个Byte.class
和Byte.TYPE
的Class<Byte>
对象.后者仅用于区分原始类型和对象类型.
实际上,Byte.TYPE定义为:
public static final Class<Byte> TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");
Run Code Online (Sandbox Code Playgroud)
并且getPrimitiveClass
是一个不透明的方法,它从VM检索类型,因此我们无法进一步调查它.
因此,即使您认为您正在传递原始数据类型Class,因为它们不存在(为什么它们应该是,因为它们引用的是根据对象的Java类型系统而不是包含原语的类型.类型,直到它们被装入包装类),你正在创建一个Vector<Byte>
.
但最终这并不重要,在达到运行时执行时,类型注释被删除,泛型类型并不意味着什么.每当你添加一个byte
它,它将被自动装箱到一个Byte
对象,就是这样.
我目前无法测试您的代码,在向运行时添加项目时会在运行时抛出异常Vector
?
jdp*_*nix 15
你偶然发现了自动装箱和拆箱.请参阅http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
坚果壳版本
List<Integer> list = new List<Integer>();
list.add(1); // works
Run Code Online (Sandbox Code Playgroud)
byte.class
,int.class
等等决心Byte
,Integer
等见Java语言规范,15.8.2:
15.8.2.类文字
......
的类型
p.class
,其中,p是一个基本类型的名称(§4.2),是Class<B>
,其中B是式P的表达的装箱转换后的类型(§5.1.7).
void.class
(§8.4.5)的类型是Class<Void>
.
没有!这不是错误.它被称为Autoboxing.当您将byte传递给期望Byte的泛型方法时,编译器会自动将其Autoboxes为Byte,这是Object的一个实例.该操作的对立被称为自动拆箱,这就是为什么像下面所示的操作是合法的.
int a = new Integer(5);
Integer b = 5;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14843 次 |
最近记录: |