Class类的asSubClass()方法

    public <U> Class<? extends U> asSubclass(Class<U> clazz) {
        if (clazz.isAssignableFrom(this))
            return (Class<? extends U>) this;
        else
            throw new ClassCastException(this.toString());
    }

这个方法实现的功能很好懂,主要是什么时候需要用到它。

其作用是将一个Class对象转换成为指定了泛型的Class对象,经常用于你不知道Class对象是什么类型的时候,例如Class.forName(str)他只能返回一个Class<?>,这时你需要将其转换为一个Class<? extends XXX>的对象(可能是添加到制定了泛型的集合里面)。

这样说还是有点抽象,有个具体的例子

  public static List<Class<? extends CompressionCodec>> getCodecClasses(Configuration conf) {
    String codecsString = conf.get("io.compression.codecs");
    if (codecsString != null) {
      List<Class<? extends CompressionCodec>> result
        = new ArrayList<Class<? extends CompressionCodec>>();
      StringTokenizer codecSplit = new StringTokenizer(codecsString, ",");
      while (codecSplit.hasMoreElements()) {
        String codecSubstring = codecSplit.nextToken();
        if (codecSubstring.length() != 0) {
          try {
            Class<?> cls = conf.getClassByName(codecSubstring);
            if (!CompressionCodec.class.isAssignableFrom(cls)) {
              throw new IllegalArgumentException("Class " + codecSubstring +
                                                 " is not a CompressionCodec");
            }
            result.add(cls.asSubclass(CompressionCodec.class));
          } catch (ClassNotFoundException ex) {
            throw new IllegalArgumentException("Compression codec " + 
                                               codecSubstring + " not found.",
                                               ex);
          }
        }
      }
      return result;
    } else {
      return null;
    }
  }

codecsString是一个类名的字符串,以逗号分隔,例如:"djava.lang.String,java.io.InputStream,java.util.List"

 现在需要将字符串里面的类名生成对应的Class对象放到List里面,并返回。

看try块的内容,首先通过Class.forName(conf.getClassByName就是调用Class.forName)获得Class<?>对象,但是这个对象是不能放到结果List里面否则会编译错误,List指定了泛型保证插入到List的对象是实现Writable接口的类。所以就需要进行转换。

在转换前做了一个类型检查,使用isAssignableFrom方法,检查通过后再进行强制转换。当然看JDK源码,asSubClass也会进行类型检查,其实这段代码完全可以改成这样

		        if (codecSubstring.length() != 0) {
		          try {
		            result.add(conf.getClassByName(
		            		codecSubstring).asSubclass(CompressionCodec.class));
		          } catch (ClassNotFoundException ex) {
		            throw new IllegalArgumentException("Compression codec " + 
		                                               codecSubstring + " not found.",
		                                               ex);
		          } catch (ClassCastException ex) {
		        	  throw new IllegalArgumentException("Class " + codecSubstring +
                              " is not a CompressionCodec");
		          }
		        }


可以看出,asSubClass这个方法会用于你不知道你持有的Class对象的泛型是什么,而且你需要进行泛型参数向下转型


Java泛型方面可能说简单了很简单,说复杂了非常复杂。由于我们大部分做Java基本上用到的都是泛型的基本使用

(List<XXX> list = new ArrayList<XXX>())来进行编译器类型检查来避免潜在的ClassCastException,有些可能纯粹是为了不让IDE发出黄色下划线的警告,涉及不到复杂的东西罢了。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值