`
zisefeiniao
  • 浏览: 174355 次
  • 性别: Icon_minigender_2
  • 来自: 成都
社区版块
存档分类
最新评论

4月2日,MLDN学习记

F# 
阅读更多
我在写日志的时候将泛型又重新写一分更好的,跟大家分享吧.

今天所讲的知识点
A 泛型的引出
B 泛型类
C 擦除泛型
D 通配符?
E 泛型上限和泛型下限
F 泛型接口
G 泛型方法
H 泛型的嵌套设置


我对知识点的分析
A 泛型的引出
当需要定义一个能接受多种数据类型的数据的类的时候,原来只能采用把其属性、setter方法的参数、getter方法的返回值的数据类型设置成Object类型,虽然这样做可以实现。在设置值的时候还要说,自动发生向上转型,但是在取出数据的时候总是涉及到强制的向下转型。
问题:
1、总是需要强制类型转换
例如:
public class Point { // 表示坐标
private Object x;
private Object y;
public Object getX() {
  return x;
}
public void setX(Object x) {
  this.x = x;
}
public Object getY() {
  return y;
}
public void setY(Object y) {
  this.y = y;
}
}
public class GenDemo01 {
public static void main(String[] args) {
  Point p = new Point();
  p.setX(11); // int --> Integer --> Object
  p.setY(20); // int --> Integer --> Object
  int x = (Integer) p.getX(); // 取出x坐标
  int y = (Integer) p.getY();// 取出y坐标
  System.out.println("x的坐标是:" + x);
  System.out.println("y的坐标是:" + y);
}
}
2、存在安全漏洞
因为其类型是Object类型,所以能接受所有的数据类型的对象。这样在取出数据的时候就不能确定能发生的向下类型操作。
例如:前面传入的字符串,而后面取出的时候可能向下转成了Integer,这样就会发生和报告错误。
public static void main(String[] args) {
  Point p = new Point();
  p.setX(10);
  p.setY("北纬220度");//此处不报错
  int x = (Integer) p.getX(); // 取出x坐标
  int y = (Integer) p.getY();// 取出y坐标    不可以
  System.out.println("x的坐标是:" + x);
  System.out.println("y的坐标是:" + y);
}


如上的两个问题可以通过泛型技术得到解决。
B 泛型类
定义格式:
class 类名称<泛型类型,泛型类型,…>{

}
即类中的数据类型,可以由外部实例化该类的对象的时候决定。
例如:
public class Point<T> { // 表示坐标
private T x; // x属性的类型由外部决定
private T y; // y属性的类型由外部决定
public Point(T x, T y) {//构造方法的参数类型也使用了泛型
  this.setX(x);
  this.setY(y);
}
public T getX() {
  return x;
}
public void setX(T x) {
  this.x = x;
}
public T getY() {
  return y;
}
public void setY(T y) {
  this.y = y;
}
}
-------------------------------
public static void main(String[] args) {
  Point<Integer> p = new Point<Integer>(10, 20);
  int x = p.getX(); // 取出x坐标
  int y = p.getY();// 取出y坐标
  System.out.println("x的坐标是:" + x);
  System.out.println("y的坐标是:" + y);
}

C 擦除泛型
如果一个类定义的时候使用了泛型,但是在使用该类的时候没有指定泛型的话,则表示擦除泛型。
泛型一旦擦出之后,将按照Object进行接收,以保证程序不出现任何的错误。
例如:
public static void main(String[] args) {
  Point p = new Point(10, 20);//此处未指定泛型的具体类型,将按照Object进行接收
  int x = (Integer) p.getX(); // 取出x坐标
  int y = (Integer) p.getY();// 取出y坐标
  System.out.println("x的坐标是:" + x);
  System.out.println("y的坐标是:" + y);
}


D 通配符?
泛型类,在使用的时候,指定Integer时和Object类型两个对象不存在可以转型的关系。
例如:
Point<Object> p1 = new Point<Object>();
Point<Integer> p2 = new Point<Integer>() ;
p1 = p2 ; // 此时无法转换

那么这个局限,在设置方法参数的时候就导致了很大的麻烦!!!
例如由此方法的定义:
public static void fun(Point po) {//如果此处不指定Point的泛型,则虽然可以接受任意类型的对象,但是是按照泛型擦除处理的,即以Object处理,又回到了原来没有泛型的问题上
}

public static void fun(Point<具体类型> po) {//如果此处指定Point的泛型,则又导致只能接受所指定的类型的对象,其他类型的对象就不可以
}
例如:public static void fun(Point< Integer > po) {},则此方法p2能调用,p1就不能调用
所以需要采用通配符?
“?”表示的是可以接收任意的泛型类型
例如:public static void fun(Point<?> po) {},这样可以接受任意类型的对象
但是只是接收输出,并不能修改
例如:
public static void fun(Point<?> po) { // 表示,此时可以接收任意的类型
         po.setX(“aa”);//错误,不能修改,因为无法确定其传入的对象的类型到底是什么,此处指定其setX()参数为字符串类型,太绝对了
  System.out.println(po.getX());
  System.out.println(po.getY());
}


E 泛型上限和泛型下限
1、泛型上限
上限就指一个操作泛型其最大的操作父类
设置型的上限语法:<T  extends  类名>,表示泛型T只能是此处指定的类型或者其子类,而不可超越此类,即不能指定其他类或者其父类。例如:现在最大的上限设置成“Number”类型,那么此时,所能够接收到的类型只能是Number及其子类(Integer)。
public class Point<T extends Number> { // 表示坐标,最高只能是Number
……………….
}
以上的泛型类型明确的指出,最大的操作父类是Number,能设置的内容只能是其子类Integer、Float等等。

2、泛型下限
泛型的下限指的是只能设置其具体的类或者父类。
设置的语法如下:<T  super  类名>
例如:现在下限设置成“Number”类型,那么此时,所能够接收到的类型只能是Number或其父类。

F 泛型接口
定义格式:interface 接口名称<泛型类型,泛型类型,…>{}
例如:
public interface Demo<T> { // 定义泛型接口
public void print(T param);//  此抽象方法中使用了泛型类型
}

实现接口的方法:
1、在实现接口的类上继续标记泛型
public class DemoImpl1<T> implements Demo<T> {
public void print(T param) {
  System.out.println("param = " + param);
}
}
-----------------------------------
public static void main(String[] args) {
  Demo<String> demo = new DemoImpl1<String>() ;
  demo.print("hello") ;
}
2、实现接口的时候指定具体的类型
public class DemoImpl2 implements Demo<DemoImpl2> {// 设置具体类型
public void print(DemoImpl2 param) {
  System.out.println("param = " + param);
}
}
因为此处指定的类型为DemoImpl2,其本身,所以此处不需要在类名后面指定< DemoImpl2>,如果此处指定的是其他类型,则还需要在类名后面加上<其他类型>
public static void main(String[] args) {
  Demo<DemoImpl2> demo = new DemoImpl2() ;
  demo.print(new DemoImpl2()) ;
}

G 泛型方法
在方法上使用泛型,此方法所在的类不一定是泛型的操作类
权限修饰符 <泛型>  返回值类型 print(参数列表){}
方法的返回值类型及其中的变量的数据类型都可以用该泛型指定。
一般其中参数都有一个是泛型指定的,那么在调用该方法的时候,根据所传递的实参的数据类型来决定该泛型的具体类型。
例如:
class Demo {
public <T> T print(T param){ // 定义泛型方法
  return param ;
}
}
public class GenDemo17 {
public static void main(String[] args) {
  Demo d = new Demo() ;
  System.out.println(d.print(1)); // 如果输入1表示类型是Integer
}
}
-----------------------------------------------------------------------------
public class GenDemo18 {
public static void main(String[] args) {
  Integer i[] = fun(1, 2, 3, 4, 5, 6, 7, 8, 9);
  for (int x : i) {
   System.out.println(x);
  }
}
public static <T> T[] fun(T... param) {
  return param; // 返回数组
}
}


H 泛型的嵌套设置
当一个类是泛型类,在实现其类的时候指定的数据类型是另一个包含泛型的类,那么这个时候就需要依次指定泛型。
例如:有一个Info泛型类
public class Info<T> {
private T param ;
public T getParam() {
  return param;
}
public void setParam(T param) {
  this.param = param;
}
}
另一个泛型类Person
public class Person<T> {
private T infos;
public T getInfos() {
  return infos;
}
public void setInfo(T info) {
  this.infos = info;
}
}
此时在实例化Person的时候指定的类型是Info类型,因为Info本身也是泛型类,那么就要先指定Info类的泛型,然后指定Person类的泛型,例如:
public static void main(String[] args) {
        //同时即要指定Person的泛型类型,又要指定Info中的泛型类型,依次指定
  Person<Info<String>> per = new Person<Info<String>>() ;
  per.setInfo(new Info<String>()) ;
  per.getInfo().setParam("mldnjava") ;
  System.out.println(per.getInfo().getParam()) ;
}




今天的问题


A public static void main(String[] args) {
String info="张三:21:98|李四:22:89|王五:20:70";
String []str=info.split("\\|");//按"|"把每个学生的信息拆分开来
Student stu[]=new Student[str.length];//根据之前拆分的学生信息的个数来确定学生对象数组大小
for(int i=0;i<stu.length ;i++){
  String []temp=str[i].split(":");

  stu[0].setName(temp[0]);//空指向异常
  stu[0].setAge(Integer.parseInt(temp[1]));//空指向异常
  stu[0].setScore(Integer.parseInt(temp[2]));//空指向异常
}
}

解决方法:
public static void main(String[] args) {
  String info="张三:21:98|李四:22:89|王五:20:70";
  String []str=info.split("\\|");//按"|"把每个学生的信息拆分开来
  Student stu[]=new Student[str.length];//根据之前拆分的学生信息的个数来确定学生对象数组大小
  for(int i=0;i<stu.length ;i++){
   String []temp=str[i].split(":");
   stu[i]=new Student(temp[0],Integer.parseInt(temp[1]),Integer.parseInt(temp[2]));
  }
}

问题描述:
对象数组的每一个元素都需要进行实例化
前天关于泛型部分不是很懂。今天看了一些资料,分析了一下代码,基本明白了。
今天在做作业题的时候犯了了对象数组元素未实例化的错误,一直报空指向异常,找了好久才找出原因,以后一定要记住。



分享到:
评论

相关推荐

    mldn学习笔记 — 网络编程

    《mldn学习笔记——网络编程》这篇博客主要探讨了计算机网络编程的相关概念和技术,结合提供的文件《215_网络编程.pdf》,我们可以深入学习这一主题。网络编程是IT领域中的核心部分,它涉及到如何通过网络进行数据...

    MLDn学习笔记 —— JDBC

    **JDBC基础与应用** Java Database Connectivity (JDBC) 是Java平台中用于访问数据库的标准Java API,它允许Java程序与各种关系型...通过阅读《220_JDBC.pdf》这份文档,你可以更深入地学习JDBC的细节和高级特性。

    MLDN_JAVASE_文档

    【MLDN_JAVASE_文档】是一份针对Java SE(标准版)的全面学习资源,由MLDN(可能是指微软学习网络或类似的教育平台)提供。这个文档集合旨在帮助初学者和进阶者掌握Java编程语言的基础知识。Java SE是Java平台的核心...

    MLDN JAVA讲座 课程PDF文档

    《MLDN JAVA讲座 课程PDF文档》是一套针对初学者的JAVA编程教程,由知名讲师李兴华编著。这套课程旨在帮助没有编程基础的人快速入门JAVA语言,并提供了丰富的实践代码,让学习者能够通过动手操作来加深理解。课程...

    MLDN_Oracle学习笔记+源码 李兴华讲解

    《MLDN_Oracle学习笔记+源码 李兴华讲解》是针对Oracle数据库系统的一份详尽学习资源,由知名讲师李兴华精心编撰。这份资料不仅包含了丰富的理论知识,还提供了源代码实例,旨在帮助学习者深入理解和掌握Oracle...

    mldn oracle学习笔记

    "mldn oracle学习笔记"是一份关于学习Oracle数据库的资源,很可能包含了从基础到高级的全方位教程,旨在帮助学习者深入理解Oracle数据库的原理和操作技巧。"魔乐"可能是这份笔记的作者或者是一个学习社区的名字,而...

    java视频教程-MLDN

    本"java视频教程-MLDN"是由知名讲师李兴华精心制作,旨在为学习者提供一套全面、深入的Java学习资源。李兴华老师以其丰富的教学经验和深厚的编程功底,确保教程内容的专业性和实用性。 在本套教程中,你将学习到:...

    李兴华 MLDN Java学习攻略

    ### 李兴华 MLDN Java学习攻略精要解析 #### 学习Java的重要性与职业前景 李兴华在《MLDN Java学习攻略》中强调,学习Java不仅仅是为了掌握一门编程语言,更深层的意义在于理解和运用面向对象的思想与开发模式。...

    MLDN学习笔记 —— Annotation

    《MLDN学习笔记——Annotation》这篇博文主要探讨的是在编程领域中,特别是Java语言中,关于Annotation(注解)的深入理解和应用。Annotation是Java语言提供的一种元数据,它为程序提供了额外的信息,这些信息可以被...

    mldn在线学习系统 代码

    【标题】"mldn在线学习系统 代码"所涉及的知识点主要集中在构建一个基于Java技术的在线学习平台。这个项目可能是一个互动的学习环境,允许用户注册、参与课程、完成练习并跟踪进度。以下是相关的重要知识点: 1. **...

    MLDN Java学习笔记(9) -多线程

    mldn 多线程 博文链接:https://zisefeiniao.iteye.com/blog/374482

    MLDN李兴华视频教程代码.rar

    【标题】"MLDN李兴华视频教程代码.rar"是一个包含与机器学习和深度学习相关的编程实践材料的压缩文件,由知名讲师李兴华教授。这个教程可能涵盖了从基础概念到高级技术的全面讲解,旨在帮助学员深入理解并掌握机器...

    《MLDN出品JAVA风暴JAVA学习的终极资料》JAVASE压缩包

    《MLDN出品JAVA风暴JAVA学习的终极资料》JAVASE压缩包是一份全面且深入的Java SE(标准版)学习资源集合。这份压缩包显然旨在为Java初学者和进阶者提供一个完整的知识体系,帮助他们在Java编程领域扎实基础,提升...

    MLDn学习笔记 —— JDK新特性(枚举)

    4. 自动序列化:枚举类型自动支持Java的序列化机制。 三、枚举的方法 1. `values()`:返回枚举类型的全部常量数组,常用于遍历枚举。 2. `valueOf(String)`:根据字符串查找对应的枚举常量,若不存在则抛出`...

    mldn oracle 基础

    4. **表空间和数据文件**:学习如何管理存储,创建和管理表空间,以及分配数据文件以存储数据库对象。 5. **安全性**:用户权限管理是Oracle中的关键部分。理解角色、权限的概念,如何创建用户、赋予权限,以及安全...

    MLDN学习笔记 —— XML学习笔记

    XML,全称Extensible Markup Language,可扩展标记语言,是一种用于标记数据的结构化语言,...通过这些学习资料,你将能够深入理解XML的各个方面,从基础语法到高级用法,从而在实际工作中更有效地处理和利用XML数据。

    mldn 反射机制课程笔记

    本人上传资源一律无需资源分,本着分享的精神希望对您有所帮助!支持mldn!支持李老师!

    北京MLDN 李兴华JSP笔记

    【标题】:“北京MLDN 李兴华JSP笔记”是李兴华老师关于JavaWeb技术,特别是JSP(JavaServer Pages)的详实学习资料,由MLDN( Multimedia Learning and Development Network,多媒体学习与发展网络)发布。...

    MLDN改版五子棋游戏

    在五子棋游戏中,可能利用了MLDN的强化学习模块,让计算机能够通过自我对弈的方式学习和提升棋艺,实现智能化的对手。 在本次改版中,我们首先关注的是BUG的修复。这些BUG可能涉及到游戏的逻辑错误、界面显示问题...

    MLDN ORACLE

    其中,“2MLDN010”看起来像是一个序列号或课程代码;“***”可能是一个电话号码或其他编号;“scott”、“tiger”、“system”、“sys”和“manager”则是Oracle数据库中常见的用户名和权限标识;“change_on_...

Global site tag (gtag.js) - Google Analytics