一:泛型:

如何正确使用Java泛型 - JJian - 博客园 (cnblogs.com)    <--点击可以查看别人写的泛型文章

java中强制类型转换 - 易小川 - 博客园 (cnblogs.com)   <--强制类型转换

(一):集合中也可以放类的实例化对象。任何一种数据类型或者对象放进容器中后都会失去原有的类型,变成 Object,用的时候从容器中取出后进行转型成所需的类型就可以了,

在Java中由于继承和向上转型,子类可以非常自然地转换成父类,但是父类转换成子类则需要强制转换。

举个例子来说明。比如系统中存在Father、Son两个对象。首先我们先构造一个Son对象,然后用一个Father类型变量引用它:

Father father = new Son();

在这里Son 对象实例被向上转型为father了,但是请注意这个Son对象实例在内存中的本质还是Son类型的,只不过它的能力临时被消弱了而已,如果我们想变强怎么办?将其对象类型还原!

Son son = (Son)father;

这条语句是可行的,其实father引用仍然是Father类型的,只不过是将它的能力加强了,将其加强后转交给son引用了,Son对象实例在son的变量的引用下,恢复真身,可以使用全部功能了。

前面提到父类强制转换成子类并不是总是成功,那么在什么情况下它会失效呢?

当引用类型的真实身份是父类本身的类型时,强制类型转换就会产生错误。例如:

Father father = new Father();

Son son = (Son) father;

这个系统会抛出ClassCastException异常信息。

简单说的话就是能力加强和减弱。Son对象能力先被减弱,之后再加强,交给了Son来引用。

以下的代码在编译时不报错,运行时错误。原因在于上面的第1点,从集合中取出时,默认是object类型,要进行类型转换。主要是第二个coin类型不合。

public class RawType_Class {public static void main(String[] args) {List list = new ArrayList<>();list.add(new Stamp());list.add(new Coin());for (Iterator i = list.iterator(); i.hasNext();) {Stamp stamp = (Stamp) i.next();}}}

我又自己简单试了试:

package practice1;public class ClassChange {public static void main(String[] args) {animal a = new doge();//没继承关系就根本不能转。继承之后多态。a的本质是doge,被animal暂时减弱animal b = new catt();//b在内存中的本质还是catt(),能力暂时被减弱,要想回复,按照以下行恢复。doge ok = new doge();catt c = (catt)b;//编译运行都正确catt d = (catt)a;//运行出错java.lang.ClassCastException,引用子类的真正类型才能成功。不是这个真正类型转化回来就要出错。shechu pp = new catt();//没有继承关系编译阶段就错误。}}class doge extends animal{}class catt extends animal{}class animal{}class people{}class shechu extends people{}
Exception in thread "main" java.lang.ClassCastException: practice1.doge cannot be cast to practice1.cattat practice1.ClassChange.main(ClassChange.java:9)

所以编译器在编译时只会检查类型之间是否存在继承关系,有则通过;而在运行时就会检查它的真实类型,是则通过,否则抛出ClassCastException异常。

   所以在继承中,子类可以自动转型为父类,但是父类强制转换为子类时只有当引用类型真正的身份为子类时才会强制转换成功,否则失败

(二)泛型:   泛型的初衷(减少强制类型转换以及确保类型安全)

针对利用继承来实现通用程序设计所产生的问题,泛型提供了更好的解决方案:类型参数。例如,ArrayList类用一个类型参数来指出元素的类型。

ArrayList<String> stringValues=new ArrayList<String>();

泛型类型变量不能是基本数据类型

就比如,没有ArrayList<double>,只有ArrayList<Double>。因为当类型擦除后,ArrayList的原始类中的类型变量(T)替换为Object,但Object类型不能存储double值。

二:以下是一段我自己写的测试,写的不好请见谅。这里我定义了一个泛型类,就相当于说明了这个类中可以通用<T>这个泛型类型了。

package myTry;public class FanXin1 {public static void main(String[] args) {Array arr = new Array();//对的arr.setT(100);Array arr2 = new Array();arr2.setT("哈哈哈哈");System.out.println(arr.getT());System.out.println(arr2.getT());//之前的这两个看似没有问题,那换成数组呢?Array[] arr3 = new Array[3];arr3[0] = new Array("wovvvcasi");arr3[1] = new Array(124);for(int i = 0;i<2;i++) {System.out.println(arr3[i].getT());}//接下来指定类型Array<Integer> arr4 = new Array<>();arr4.setT(1);//只能放数字,其他类型会出错。}
}
//定义泛型
class Array<T>{//看示例里面咋用。private T t;public Array() {}public Array(T t) {this.t = t;}public T getT() {return t;}public void setT(T t) {this.t = t;}}
100
哈哈哈哈
wovvvcasi
124

泛型方法:

<T>说明是泛型类型,T是返回值类型,参数里面的T就是参数类型了。

package myTry;public class FanXin2 {public static void main(String[] args) {Array2 ar2 = new Array2();System.out.println(ar2.show("sdfsdf"));System.out.println(ar2.show(true));System.out.println(ar2.show(12345));}}class Array2{public <T> T show(T t) {//中间的T就是返回类型。<T>说明是泛型类型,说明统一是这个格式。return t;}
}
sdfsdf
true
12345

泛型方法和泛型接口或泛型类:

定义泛型方法,同样要有<T>说明使用了泛型,其余的和之前同理。在泛型接口下或者泛型类下,可以用泛型定义变量等等。可以用多个泛型作为参数(不知道咋表达出来,可以看下面的代码)。

package myTry;public class FanXin2 {public static void main(String[] args) {Array2 ar2 = new Array2();System.out.println(ar2.show("sdfsdf"));System.out.println(ar2.show(true));System.out.println(ar2.show(12345));}}class Array2 {public <T> T show(T t) {// 中间的T就是返回类型。<T>说明是泛型类型,说明统一是这个格式。return t;}
}interface Array3<T> {// 这里放<T>则说明使用泛型,之后的类型自己跟着变。T show(T t);//泛型T在这里是泛型接口。<M> T opps(T t,M m);//定义泛型方法
}class Array3imple<T> implements Array3<T> {// 这里用T是因为实现类要实现抽象类,需要泛型类型。public T show(T t) {return t;}@Overridepublic <M> T opps(T t, M m) {// TODO Auto-generated method stubreturn null;}
}class Array4<T> implements Array3<T>{@Overridepublic T show(T t) {// TODO Auto-generated method stubreturn null;}@Overridepublic <M> T opps(T t, M m) {// TODO Auto-generated method stubreturn null;}}

泛型方法:
不确定方法参数类型时

public <T> void test(T t){
    System.out.println(t.getClass().getName);
}
调用时可以传入任意类型的参数,根据传入参数类型决定参数类型

(三)类型通配符:

通配符的上限和下限:

以下是我自己写的一段测试,写的不好请见谅。(针对通配符上限和下限)

看代码时记得看清楚子类父类分别是哪些!

List是泛型类,建议使用这个进行测试

package myTry;import java.util.ArrayList;
import java.util.List;public class TongPeiFu {public static void main(String[] args) {
//      MaykiParent may = new MaykiParent();
//      Student stu = new Student();
//      MaykiParent stu2 = new Student();List<MaykiParent> maykiParent = new ArrayList();ArrayList<Student> student = new ArrayList();ArrayList<Son> son = new ArrayList();//先来测试extends(下限),MaykiParent是Student的父类。print(maykiParent);print(student);print(son);//下限能接受自己和子类,所以不会报错ArrayList<Integer> integer = new ArrayList();
//      print(integer);//报错input(maykiParent);
//      input(son);//上限的就不能接受子类了。所以这里报错。但上限能接受自己和父类}public static void print(List<? extends MaykiParent> list) {//这里前提应该是泛型类System.out.println("第一种");}public static void input(List<? super Student> list) {System.out.println("第二种");}
}class MaykiParent{
//  public void print(MaykiParent<? extends MaykiParent> x) //这里用这个测试是错的,推荐用List集合类测试。 }class Student extends MaykiParent{}class Son extends Student{}
第一种
第一种
第一种
第二种

(这张图截取自b站)

简单来说,比如是super MayiktParent,就是它本身或者它的父类都能被这个泛型方法接受。extends MayiktParent,就是它本身和它的子类都可以被这个定义的泛型方法接受。

(四):可变参数: 

以下是我自己写的一段测试:

package myTry;public class KeBianCanShu {//可变参数:参数动态可变(我觉得这个了解即可)//使用可变参数前:(这样的话,即使要重载,也要在以后不断改变函数的参数)public static int sum(int a,int b) {return a+b;}public static int sum(int a,int b,int c) {return a+b+c;}//使用可变参数后:public static int sum2(int... a) {//格式就是括号中显示的那样。int result = 0;for(int i = 0;i<a.length;i++) {result += a[i];//就相当于了一个数组,你传入多少参数,数组就有多少个值。}return result;}public static void main(String[] args) {System.out.println(sum2(1,1,1,1,1));System.out.println(sum(1,1));}}

(五):泛型的擦除(不太懂,简单百度了一下):

泛型,是在编译阶段限制传递的类型。

转化成 .class文件过后,就在文件中擦除了泛型,下图经过反编译发现了其实是Object类型,不是泛型类型。

(图片来自b站)

过渡篇(1),初步了解Java泛型相关推荐

  1. 3万字死磕Java泛型所有细节知识点,看这一篇就够了

    1 泛型 1.0 前言--为什么要死磕Java泛型 不知道阅读这篇文章的你是否曾跟我一样,在没有阅读<Java核心技术>前查阅了大量的Java泛型文章,但是在实际使用泛型的过程中,总是觉得 ...

  2. 【Java 泛型】使用上下边界通配符解决泛型擦除问题

    文章目录 前言 一.使用上边界通配符示例 二.分析字节码的附加信息 前言 上一篇博客 [Java 泛型]泛型用法 ( 泛型编译期擦除 | 上界通配符 <? extends T> | 下界通 ...

  3. Java泛型进阶篇: 无界通配符、上界通配符以及下界通配符

    专栏文章导航 Java泛型入门篇: 泛型类.泛型接口以及泛型方法 Java泛型进阶篇: 无界通配符.上界通配符以及下界通配符 Java泛型原理篇: 类型擦除以及桥接方法 文章目录 前言 1. 无界通配 ...

  4. 学妹不懂Java泛型,非让我写一篇给她看看(有图为证)

    前言 在学习java掉头的日子里很多青年脱坑,同时也有很多青年入坑,但入坑的时候可能没有什么好的指导或者学习方法可能头发掉的一发不可收拾-- 笔者有个学妹就遇到了相同的境遇,学弟被泛型搞得头晕目眩,搞 ...

  5. JAVA泛型的基本使用

    Java1.5版本号推出了泛型,尽管这层语法糖给开发者带来了代码复用性方面的提升,可是这只是是编译器所做的一层语法糖,在真正生成的字节码中,这类信息却被擦除了. 笔者发现非常多几年开发经验的程序猿,依 ...

  6. 用了这么多年的 Java 泛型,你对它到底有多了解?|原创

    作为一个 Java 程序员,日常编程早就离不开泛型.泛型自从 JDK1.5 引进之后,真的非常提高生产力.一个简单的泛型 T,寥寥几行代码, 就可以让我们在使用过程中动态替换成任何想要的类型,再也不用 ...

  7. java泛型的逆变_Java泛型的逆变

    在上篇<Java泛型的协变>这篇文章中遗留以下问题--协变不能解决将子类型添加到父类型的泛型列表中.本篇将用逆变来解决这个问题. 实验准备 我们首先增加以下方法,见代码清单1所示. 代码清 ...

  8. Java学习笔记(43)——Java泛型

    为什么80%的码农都做不了架构师?>>>    其实Java的泛型和C#的泛型是一样的道理,说白了就是"类型参数化",没什么神秘的,所以这篇就说说Java泛型的一 ...

  9. Java泛型中? 和 ? extends Object的异同分析

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 刘一手 来源 | 公众号「锅外的大佬」 Jav ...

最新文章

  1. Redis 笔记(01)— 安装、启动配置、开启远程连接、设置密码、远程连接
  2. Java中取两位小数
  3. LeetCode每日一题: 单值二叉树(No.965)
  4. 黑马程序员-------------(十)Java基础知识加强(一)
  5. C++之手写strlen函数
  6. 用对拍程序来debug错误程序的错误数据
  7. python中文编程教学_中谷python中文视频教程(全38集)
  8. 防删库实用指南 | 只需一步,快速召回被误删的表
  9. HTTP Response Splitting攻击探究 转
  10. asp.net MVC ViewData详解
  11. 智能仪器原理及设计C语言,智能仪器仪表课程设计.doc
  12. 熊猫入金讲为什么seo没效果
  13. Windows10 adb安装与环境变量配置
  14. input maxlength 属性不起作用
  15. JavaScript Navigator
  16. 文件系统错误(-1073740791)解决办法
  17. 苹果手机python软件_python编程教学app
  18. 2017年3月18日奇虎360 笔试真题(3个编程题)
  19. 在线电子书阅读微信小程序 毕业设计(5)用户登录注册
  20. (二)计算机取证-案件确认书及证据表

热门文章

  1. csv文件查找指定内容
  2. 计算机在开机后显示器在显示桌面,电脑开机后显示器黄灯怎么办
  3. 餐饮店选址要考虑竞品分布,用户画像等
  4. 墨客 去中心化平台的商业逻辑
  5. java与单片机通信_Java实现串口通信与单片机通信实例..【Pnoter】
  6. 2019年天梯赛-全国总决赛-L2-032 彩虹瓶 (25 分)
  7. [投资理念]沃伦-巴菲特的12条忠告
  8. 计算机硬件之间是怎样联系的,计算机硬件系统和软件系统有没有联系
  9. unity投篮小游戏,原创,请勿转载。
  10. 声源定位与stm32示例