黑马程序员_反射和泛型---------------------- <a href="http://edu.csdn.net/heima" target="blank">android培训</a>、<a href="http://edu.csdn.net/heima" target="blank">java培训</a>、期待与您交流! ----------------------
从jdk1.5以后,java的class类增加了泛型功能,从而允许使用泛型来限制Class类,例如,String.class的类型实际上是Class<String>。如果将Class对应的类暂时未知,则使用Class<?>。通过在反射中使用泛型,可以避免使用反射生成的对象需要强制类型转换。
下面提供一个简单的对象工厂,该对象工厂可以根据指定类来提供该类的实例。
public class A
{
public static Object get(String clsName)
{
Try
{
Class cls=Class.forName( clsName);
Return cla.newInstance();
}
catch(Exception e)
{
e.printStatckTrace();
return null;
}
}
}
上面程序中两行红体字代码根据指定的字符串类型创建了一个新对象,但这个对象的类型是Object,因此当我们需要使用YeekuObjectFactory的getInstance()方法来创建对象时,将会看到如下代码
Date d=(Date)YeekuObjectFactor.getInstace("java.util.Date");
JFrame f=(JFrame)YeekuObjectFactory.getInstance(java.util.Date");
上面代码在编译时不会有任何问题,但运行时侯将抛出ClassCastException异常,因为程序强制将一个Date对象转换成JFrame对象
如果我们将上面的YeekuObjectFactory工厂类改写成使用泛型后的Class,就可以避免这种情况。
public class B
{
public static <T> T getInstance(Class<T> cls)
{
try
{
return cls.newInstance();
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
public static void main(String[] args)
{
Date d=YeekuObjectFactory2.getInstance(Date.class);
JFrame f=YeekuObjectFactory2.getInatance(JFrame.class);
}
}
在上面程序的getInstance()方法中传入一个Class<T>参数,这是一个泛型化的Class对象,调用该Class对象的newInstance()方法将返回一个T对象,如程序中粗体字代码所示。接下来当我们使用YeekuObjectFactory2工厂类的getInstance()方法来产生对象时,无需使用强制类型转换,系统会执行更严格的检查,不会出现ClassCastException运行使异常。
对于上面的代码其实并不是非常方便,因为我们知道newInstanc方法返回的确实是一个String数组,而不是简单的Object对象。如果我们需要将arr对象当成String数组使用时,必须再次使用强制类型转换——这是不安全的操作
为了解决这个问题,我们可以对Array的newInstance方法进行包装。
public class C
{
public static <T> T[] newInstanc(Class<T> componentType,int length)
{
return(T[])Array.newInstance(componentType,length);
}
public static voie main(String args[])
{
String[] arr=YeekuArray.newInstance(String.class,10);
int[][] intArr=YeekuArray.newInstance(int[].class,5);
arr[5]="ROR敏捷开发最佳实战";
intArr[1]=new int[]{23,12};
System.out.println(arr[5]);
System.out.println(intArr[1][1]);
}
}
上面程序中红体字代码定义的newInstance()_方法对Array类提供的newInstance方法进行了包装,将方法签名改成了public static<T> T[] newInstance(Class<T>componentType,int length),这就保证程序通过该newInstance()方法创建数组时的返回值就是数组对象,而不是Object对象,从而避免了强制类型转换---------------------- <a href="http://edu.csdn.net/heima" target="blank">android培训</a>、<a href="http://edu.csdn.net/heima" target="blank">java培训</a>、期待与您交流! ----------------------