深入学习java源码之 Array.newInstance()与Array.get()

Class<T>与Class<?>

Class<T>在实例化的时候,T要替换成具体类,固定的泛型指类型是固定的,比如:Interge,String.

Class<?>它是个通配泛型,?可以代表任何类型 ,<?>没有extends,则默认是允许Object及其下的任何Java类了。也就是任意正在运行的类。

Object类中包含一个方法名叫getClass,利用这个方法就可以获得一个实例的类型类。类型类指的是代表一个类型的类,因为一切皆是对象,类型也不例外,在Java使用类型类来表示一个类型。所有的类型类都是Class类的实例。getClass()会看到返回Class<?>。

JDK中,普通的Class.newInstance()方法的定义返回Object,要将该返回类型强制转换为另一种类型;

public class Object {
public final native Class<?> getClass();
}

创建一个Class<T>类型的实例,但是使用泛型的Class<T>,Class.newInstance()方法具有一个特定的返回类型;

public class Gen<T> {  

// 定义泛型成员变量
private T t;

public Gen(T t) {
this.t = t;
}

public T getT() {
return t;
}

public void setT(T t) {
this.t = t;
}

public void showType() {
System.out.println("T的实际类型是: " + t.getClass().getName());
}

public static void main(String[] args) {
// 定义一个泛型类Gen的一个Integer的版本
Gen<Integer> intObj = new Gen<Integer>(0);
intObj.showType();

int i = intObj.getT();
System.out.println(" value = " + i);
System.out.println(" ====================== ");

//定义泛型类Gen的一个String的版本
Gen<String>strObj = new Gen<String>("Hello Gen!");
strObj.showType();
String s = strObj.getT();
System.out.println(" value = " + s);
}
}

 

泛型方法,与其所在的类是否泛型没有关系。要定义泛型方法,只需将泛型参数列表置于方法的修饰符(public,static,final,abstract等)之后,返回值声明之前。

public static <T> T request2Bean(HttpServletRequest request,Class<T> clazz){}

其中第一个<T>是与传入的参数Class<T>相对应的,相当于返回值的一个泛型,后面的T是返回值类型,代表方法必须返回T类型的(由传入的Class<T>决定)

调用方法 Class.forName() 或者使用类常量X.class。 Class.forName() 被定义为返 回 Class<?>。另一方面,类常量 X.class 被定义为具有类型 Class<X>,所 以 String.class 是Class<String> 类型的。

使用泛型方法时,不必指明参数类型,​​编译器​​会自己找出具体的类型。泛型方法除了定义不同,调用就像普通方法一样。

需要注意的是,一个static方法,无法访问泛型类的类型参数,所以,若要static方法需要使用泛型能力,必须使其成为泛型方法。

public <T> void print(T x) {  
System.out.println(x.getClass().getName());
}

public static void main(String[] args) {
GenericMethod method = new GenericMethod();
method.print(" ");
method.print(10);
method.print('a');
method.print(method);
}

java.lang.String

java.lang.Integer

java.lang.Character

com.wsheng.aggregator.generic.GenericMethod

 

方法

Modifier and Type

Method and Description

​static Object​

​get(Object​

返回指定数组对象中的索引组件的值。

​static boolean​

​getBoolean(Object​

返回指定数组对象中的索引组件的值,如 ​​boolean​​ 。

​static byte​

​getByte(Object​

返回指定数组对象中的索引组件的值,如 ​​byte​​ 。

​static char​

​getChar(Object​

返回指定数组对象中索引组件的值,如 ​​char​​ 。

​static double​

​getDouble(Object​

返回指定数组对象中的索引组件的值,如 ​​double​​ 。

​static float​

​getFloat(Object​

返回指定数组对象中的索引组件的值,如 ​​float​​ 。

​static int​

​getInt(Object​

返回指定数组对象中的索引组件的值,如 ​​int​​ 。

​static int​

​getLength(Object​

返回指定数组对象的长度,如 ​​int​​ 。

​static long​

​getLong(Object​

返回指定数组对象中索引组件的值,如 ​​long​​ 。

​static short​

​getShort(Object​

返回指定数组对象中的索引组件的值,如 ​​short​​ 。

​static Object​

​newInstance(类<?> componentType, int... dimensions)​

创建具有指定组件类型和尺寸的新数组。

​static Object​

​newInstance(类<?> componentType, int length)​

创建具有指定组件类型和长度的新数组。

​static void​

​set(Object array, int index, Object​

将指定数组对象的索引组件的值设置为指定的新值。

​static void​

​setBoolean(Object​

将指定数组对象的索引组件的值设置为指定的 ​​boolean​​值。

​static void​

​setByte(Object​

将指定数组对象的索引组件的值设置为指定的 ​​byte​​值。

​static void​

​setChar(Object​

将指定数组对象的索引组件的值设置为指定的 ​​char​​值。

​static void​

​setDouble(Object​

将指定数组对象的索引组件的值设置为指定的 ​​double​​值。

​static void​

​setFloat(Object​

将指定数组对象的索引组件的值设置为指定的 ​​float​​值。

​static void​

​setInt(Object​

将指定数组对象的索引组件的值设置为指定的 ​​int​​值。

​static void​

​setLong(Object​

将指定数组对象的索引组件的值设置为指定的 ​​long​​值。

​static void​

​setShort(Object​

将指定数组对象的索引组件的值设置为指定的 ​​short​​值。

java源码

package java.lang.reflect;

public final
class Array {

private Array() {}

public static Object newInstance(Class<?> componentType, int length)
throws NegativeArraySizeException {
return newArray(componentType, length);
}

public static Object newInstance(Class<?> componentType, int... dimensions)
throws IllegalArgumentException, NegativeArraySizeException {
return multiNewArray(componentType, dimensions);
}

public static native int getLength(Object array)
throws IllegalArgumentException;

public static native Object get(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native boolean getBoolean(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native byte getByte(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native char getChar(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native short getShort(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native int getInt(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native long getLong(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native float getFloat(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native double getDouble(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native void set(Object array, int index, Object value)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native void setBoolean(Object array, int index, boolean z)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native void setByte(Object array, int index, byte b)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native void setChar(Object array, int index, char c)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native void setShort(Object array, int index, short s)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native void setInt(Object array, int index, int i)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native void setLong(Object array, int index, long l)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native void setFloat(Object array, int index, float f)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

public static native void setDouble(Object array, int index, double d)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException;

private static native Object newArray(Class<?> componentType, int length)
throws NegativeArraySizeException;

private static native Object multiNewArray(Class<?> componentType,
int[] dimensions)
throws IllegalArgumentException, NegativeArraySizeException;
}

抛出表示一种方法已经通过了非法或不正确的参数。 

package java.lang;

public
class IllegalArgumentException extends RuntimeException {

public IllegalArgumentException() {
super();
}

public IllegalArgumentException(String s) {
super(s);
}

public IllegalArgumentException(String message, Throwable cause) {
super(message, cause);
}

public IllegalArgumentException(Throwable cause) {
super(cause);
}

private static final long serialVersionUID = -5365630128856068164L;
}

抛出以表示使用非法索引访问数组。 索引为负数或大于或等于数组的大小。 

package java.lang;

public
class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
private static final long serialVersionUID = -5116101128118950844L;

public ArrayIndexOutOfBoundsException() {
super();
}

public ArrayIndexOutOfBoundsException(int index) {
super("Array index out of range: " + index);
}

public ArrayIndexOutOfBoundsException(String s) {
super(s);
}
}

抛出以表示某种索引(例如数组,字符串或向量)的索引超出范围。 
应用程序可以将此类子类化以指示类似的异常。 

package java.lang;

public
class IndexOutOfBoundsException extends RuntimeException {
private static final long serialVersionUID = 234122996006267687L;

public IndexOutOfBoundsException() {
super();
}

public IndexOutOfBoundsException(String s) {
super(s);
}
}