最近在帝都好无聊啊, 排遣寂寞就只有让自己不要停下来,不断的思考了 QWQ;

最近做ndk, java有点忘了,突然看到了一些java范型方面的问题, 踌躇了一会, 想着想着,决定还是写个随笔记录下来。

范型语法这个网上找度娘可以要到一大把, 我就不记了, 主要是范型上下限问题。

案例:

public class Test {

  public static class Base{

  }

  public static class A extends Base{

  }

  public static class Fanxin<T>{

  T t;

  public T get(){

  return t;

  };

  public void set(T t){

  this.t = t;

  }

}

public static class B extends A{

}

  public static void main(String[] arvg){

    Fanxin<? extends Base> fanxin = new Fanxin<A>();

    Base a = fanxin.get();

    //fanxin.set(new A()); 1编译报错

    Fanxin<? super A> fanxin1 = new Fanxin<Base>();

    A obj = (A)fanxin1.get();

    //A obj = fanxin1.get(); 2编译报错

    //fanxin1.set(new Base());3编译报错

    fanxin1.set(new A());

  }

}

首先java范型我理解的是为了安全, 这样可以在编译期检测类型,而不会到运行的时候出现类型转化异常。 第一个 fanxin.set(new A());报错,是因为,这里类型是定义了上限,所以这里通配符代表的类型是base或者base的子类, 虽然A是base的子类, 但是这是不安全的,考虑这种情况:

Fanxin<B> fanxin = new Fainxin<B>();

......各种操作......

Fanxin<? extends Base> fanxin1 = fanxinB;

fanxin1.set(new A());

B b = fanxin.get();//这里有问题

这时候不安全的因素发生了,我们对fanxin1设置了一个对象A, 但是fanxin1实质是fanxin<B>对象, 这时候如果我们fanxin.get()获得的实际上是A对象,运行的时候会有类型转化异常。

这样是不安全的, 所以编译的时候会报错,如果一定要set, 那么可以强制类型转换来做,但是这样也失去了意义:

Fanxin<A> fanxinA = (Fanxin<A>)fanxin1;

fanxinA.set(new A());

第二个问题,通配符是A或者A的父类, 所以我们可以赋值, 面向对象的原则是子类可以替代父类, 所以是安全的。 但是如果我们读区值,然后赋值给其他对象,那么就会有问题, 比如;

Fanxin<Base> fanxinBase = new Fanxin<Base>();

Fanxin<? super A> fanxin1 = fanxinBase;   //Fanxin<? super A> fanxin = new Fanxin<? super A>();编译报错

A a =  fanxin1.get();

这里fanxin1.get()实际获得的是Base类, 赋值给A类,编译会报错, 运行的时候会有类型转化异常。

当然如果我们知道这个类的类型,那么我们也可以用强制类型转换避免编译报错。

例:

Base b = (Base) fanxin1.get();

总之 ?是范型里面的通配符,extends, super只是提供上下限的信息给编译起, 通配符有集合的概念在里面,Fanxin< ? extends Base>, ?类型可能是Base的任何子类,所以我们不能有赋值操作,因为子类和子类是不同的类型,只是子类可以替换父类而已,所以可以按父类来读取值, Fanxin<? super A>, ?类型是A的超类, 所以我们可以将A的任何子类赋值给他,这样是安全的,但是读取的时候,是无法知道这是什么类型的,但是java类都是Object类的扩展, 所以可以获取值赋给obj对象, Object obj = fanxin.get(); 如果要赋值给其他对象那么只有强制类型转换了。

Java范型随笔的更多相关文章

  1. Java范型

    泛型不用考虑对象的具体类型.优点在于,因为不用考虑对象的具体类型所以可以对一类对象执行一定的相同操作:缺点在于,因为没有考虑对象的具体类型所以就不能使用对象自带的接口函数.泛型的最佳用同是实现容器类. ...

  2. Java范型学习笔记

    对于范型的使用或者说印象只有集合,其他地方即使使用过也不知道,反正就是只停留在List<E> Map<K, V>,最近刚好闲来无事,就找找资料学习一下:下列为个人学习总结,欢迎 ...

  3. java范型集合中的成员排序

    范型集合中的类是JsonObject,不是自定义类,如果是自定义类就直接取要比较的字段值. ArrayList<JSONObject> TList = new ArrayList<J ...

  4. 关于java范型

    1 范型只在编译阶段有效 编译器在编译阶段检查范型结果之后,就会将范型信息删除.范型信息不会进入运行时阶段. 泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型. 2 不能对确定的范型 ...

  5. Java范型之T extends Comparable<? super T>

    在观察Java源码的时候,发现了这么一个写法T extends Comparable<? super T>.不禁纳闷为什么要这么写呢?有什么好处吗,extends和super在这里的作用着 ...

  6. 范型方法 & 范型参数 & 范型返回值

    Java范型类 public class FanXingClassTest { public static void main(String args[]){ Test<Integer> ...

  7. Java Comparator的范型类型推导问题

    问题 在项目中,有一处地方需要对日期区间进行排序 我需要以日期区间的开始日为第一优先级,结束日为第二优先级进行排序 代码 我当时写的代码如下: List<Pair<LocalDate, L ...

  8. Java数组协变与范型不变性

    变性是OOP语言不变的大坑,Java的数组协变就是其中的一口老坑.因为最近踩到了,便做一个记录.顺便也提一下范型的变性. 解释数组协变之前,先明确三个相关的概念,协变.不变和逆变. 一.协变.不变.逆 ...

  9. Java数据结构与算法分析-第一章(引论)-Java中的范型<T,E>构件

    一.为什么需要使用范型? 官方的说法是:Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质 ...

随机推荐

  1. [zz] Pixar’s OpenSubdiv V2: A detailed look

    http://www.fxguide.com/featured/pixars-opensubdiv-v2-a-detailed-look/ Pixar’s OpenSubdiv V2: A detai ...

  2. Linux Bash 使用$?来防止一些误删操作

    在shell脚本中如果不加任何检查机制,很有可能导致误删的出现,例如: cd $remove_directory rm * 这段代码的目的是删除目标目录下所有的文件.但是如果目标目录由于输入错误等原因 ...

  3. CGContextAddArcToPoint和CGContextAddArc

    比较难的是CGContextAddArcToPoint 代码如下: CGContextRef context=UIGraphicsGetCurrentContext(); CGContextSetRG ...

  4. 黑马程序员_ C语言基础(一)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------ 开发过程: 编写->编译(只编译源文件,编译成*.o  只会检测语法是否合理,不会检测函数是 ...

  5. (整理)IIS 7 503 "service unavailable" errors

    原文地址:http://mvolo.com/where-did-my-iis7-server-go-troubleshooting-503-quotservice-unavailablequot-er ...

  6. Hardmard 变换

    阿达马(Hadamard)矩阵是由+1和-1元素构成的正交方阵.阿达马变换多被用来计算SATD(一种视频残差信号大小的衡量). 这里介绍三个内容,1. SATD 2. H264中阿达马的应用 3. 阿 ...

  7. 有关RAVE报表 - 大富翁论坛20050419

    部分资料来源于RAVE开发人员指南 ravedevguide5 新闻组News.Nevrona.com RAVE的官方主页  www.nevrona.com/rave KeyLife富翁笔记  作者 ...

  8. JS-改变页面的颜色(一)

    需求:点击页面的按钮,改变页面的颜色 思路:一先画出最简单的页面,二想办法获取页面的body节点,三想办法修改body节点的背景颜色属性,四通过一个方法获取随机的颜色值 简单的代码片段如下所示: &l ...

  9. xml 中转意字符&\/使用方法

    所有 XML 元素都须有关闭标签 在 HTML,经常会看到没有关闭标签的元素: <p>This is a paragraph <p>This is another paragr ...

  10. 关于启用 HTTPS 的一些经验分享

    https://imququ.com/post/sth-about-switch-to-https.html 随着国内网络环境的持续恶化,各种篡改和劫持层出不穷,越来越多的网站选择了全站 HTTPS. ...