美文网首页
记录一个有趣的实现

记录一个有趣的实现

作者: 谷歌清洁工 | 来源:发表于2017-02-28 23:27 被阅读0次

    定义在BaseFragment里的方法:

     /**
       * Gets a component for dependency injection by its type.
       */
     @SuppressWarnings("unchecked")
      protected <C> C getComponent(Class<C> componentType) {
        return componentType.cast(((HasComponent<C>) getActivity()).getComponent());
      }
    

    HasComponent接口:

    public interface HasComponent<C> {
      C getComponent();
    }
    

    具体Activity接上此接口并实现方法。

    @Override public UserComponent getComponent() {
        return userComponent;
      }
    

    在BaseFragment子类里调用此方法获得UserComponent对象并注入:

     this.getComponent(UserComponent.class).inject(this);
    

    翻开布满灰层的Java编程思想回忆一下相关概念:

    泛化的Class引用:

    Class引用总是指向某个Class对象,它可以制造类的实例,并包含可作用于这些实例的所有方法代码。它还包含该类的静态成员,因此,Class引用表示的就是它所只想的对象的确切类型,而该对象便是Class类的一个对象。

    Class<Integer> IntClass=int.class;
    IntClass=Integer.class;
    //IntClass=double.class   //illegal
    

    向Class引用添加泛型语法的原因仅仅是为了提供编译器类型检查,因此如果你操作有误,稍后立即会发现这一点。而当你将泛型语法用于Class对象时:newInstance()会返回该对象的确切类型,而不仅是Object。
    这在某些程度上有点受限:

    Class<FancyToy> ftClass=FancyToy.class;
    Class<? super FancyToy> up=ftClass.getSuperClass();
    //This won't compile
    //Class<Toy> up2=ftClass.getSuperclass();
    //Only Produces Object;
    Object obj=up.newInstance();
    

    如果你手头是超类,那编译器将只允许你声明超类引用是“某个类,它是FancyToy超类”,就像在
    表达式Class<? super FancyToy> 所看到的,而不会接受Class<Toy>这样的声明。这看上去有点怪,因为getSuperClass()方法返回的是基类(不是借口),并且编译器在编译器就知道它是什么类型了----在本例中就是Toy.class----而不仅仅是“某个类,它是FancyToy超类”.不管怎样,正是由于这种含糊性,up.newInstance()返回值不是精确类型,而只是Object.

    Cast:

    cast()方法接受参数对象,并将其转型为Class引用的类型。当你编写泛型代码,如果你存储了Class引用,并希望以后通过这个引用来执行转型,这种情况就会发生。

    Building b=new House();
    Class<House> houseType=House.class;
    House h=houseType.cast(b);
    

    相关文章

      网友评论

          本文标题:记录一个有趣的实现

          本文链接:https://www.haomeiwen.com/subject/dnmfgttx.html