深入学习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 array, int index) 返回指定数组对象中的索引组件的值。 |
static boolean | getBoolean(Object array, int index) 返回指定数组对象中的索引组件的值,如 |
static byte | getByte(Object array, int index) 返回指定数组对象中的索引组件的值,如 |
static char | getChar(Object array, int index) 返回指定数组对象中索引组件的值,如 |
static double | getDouble(Object array, int index) 返回指定数组对象中的索引组件的值,如 |
static float | getFloat(Object array, int index) 返回指定数组对象中的索引组件的值,如 |
static int | getInt(Object array, int index) 返回指定数组对象中的索引组件的值,如 |
static int | getLength(Object array) 返回指定数组对象的长度,如 |
static long | getLong(Object array, int index) 返回指定数组对象中索引组件的值,如 |
static short | getShort(Object array, int index) 返回指定数组对象中的索引组件的值,如 |
static Object | newInstance(类<?> componentType, int... dimensions) 创建具有指定组件类型和尺寸的新数组。 |
static Object | newInstance(类<?> componentType, int length) 创建具有指定组件类型和长度的新数组。 |
static void | set(Object array, int index, Object value) 将指定数组对象的索引组件的值设置为指定的新值。 |
static void | setBoolean(Object array, int index, boolean z) 将指定数组对象的索引组件的值设置为指定的 |
static void | setByte(Object array, int index, byte b) 将指定数组对象的索引组件的值设置为指定的 |
static void | setChar(Object array, int index, char c) 将指定数组对象的索引组件的值设置为指定的 |
static void | setDouble(Object array, int index, double d) 将指定数组对象的索引组件的值设置为指定的 |
static void | setFloat(Object array, int index, float f) 将指定数组对象的索引组件的值设置为指定的 |
static void | setInt(Object array, int index, int i) 将指定数组对象的索引组件的值设置为指定的 |
static void | setLong(Object array, int index, long l) 将指定数组对象的索引组件的值设置为指定的 |
static void | setShort(Object array, int index, short s) 将指定数组对象的索引组件的值设置为指定的 |
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);
}
}