目录

11.1 枚举

11.1 使用枚举类型设置常量

11.1.2 深入了解枚举类型

11.1.3 使用枚举类型的优势

11.2 泛型

11.2.1 回顾 “向上转型” 与 “向下转型”

11.2.2 定义泛型类

11.2.3 泛型的常规类型

11.2.4 泛型的高级用法

11.3 小结


11.1 枚举

枚举概念:它是一系列具有名称的常量的集合。比如:在数学中所学的集合: A = {1,2,3}, 当使用这个集合时,只能使用集合中的1,2,3这三个元素,不是这3个元素的值就无法使用。Java中的枚举同理,eg: 在程序中定义了一个性别枚举,里面只用两个值:男,女,那么在使用该枚举时,只能使用男和女这两个值,其他的任何值都是无法使用的。  本节介绍枚举如下:

11.1.1 使用枚举类型设置常量

以往设置常量,通常将常量放置在接口中,这样在程序中就可以直接使用,并且该常量不能被修改,因为在接口中定义常量时,该常量的修饰符为 final 与 static。

例如,在项目中创建Constants接口,在接口中定义常量的规范方式。

public interface Constants {

public static final int Constants_A = 1;

public static final int Constants_B =12;

}

在JDK1.5 版本中新增枚举类型后就逐渐取代了这种常量定义方式,因为通过使用枚举类型,可以赋予程序在编译是进行检查的功能。使用枚举类型定义常量的语法如下:

public enum Constants{

Constants_A ;

Constants_B ;

Constants_C ;

其中,enum 是定义枚举类型的关键字。当需要在程序中使用该常量时,可以使用  Constants.Constants_A来表示。举栗子说明:

interface Constants { // 将常量放置在接口中public static final int Constants_A = 1;public static final int Constants_B = 12;
}
public class test12{enum Constants2 { // 将常量放置在枚举类型中Constants_A, Constants_B}// 使用接口定义常量public static void doit(int c) { // 定义一个方法,这里的参数为int型switch (c) { // 根据常量的值做不同操作case Constants.Constants_A:System.out.println("doit() Constants_A");break;case Constants.Constants_B:System.out.println("doit() Constants_B");break;}}public static void doit2(Constants2 c) { // 定义一个参数对象是枚举类型的方法switch (c) { // 根据枚举类型对象做不同操作case Constants_A:System.out.println("doit2() Constants_A");break;case Constants_B:System.out.println("doit2() Constants_B");break;}}public static void main(String[] args) {test12.doit(Constants.Constants_A); // 使用接口中定义的常量test12.doit2(Constants2.Constants_A); // 使用枚举类型中的常量test12.doit2(Constants2.Constants_B); // 使用枚举类型中的常量test12.doit(3);// ConstantsTest.doit2(3);}
}
package com.lzw;public class ConstantsTest {enum Constants2 {  //将常量放置在枚举类型中constants_A, Constants_B}public static void doit2(Constants2 c) {  //定义一个参数对象是枚举类型的方法switch (c) {         //根据枚举类型对象做不同操作case constants_A:System.out.println("doit2() Constants_A");break;case Constants_B:System.out.println("doit2() Constants_B"); break;}}public static void main(String[] args) {// TODO Auto-generated method stubConstantsTest.doit2(Constants2.constants_A);//使用枚举类型中的常量ConstantsTest.doit2(Constants2.Constants_B);//使用枚举类型中的常量}}

11.1.2 深入了解枚举类型

枚举类型较传统定义常量的方式,除了具有参数类型检测的优势之外,还具有其他方面的优势。用户可以将一个枚举类型看作是一个类,它继承于java. lang. Enum类,当定义一个枚举类型时,每一个枚举类型成员都可以看作是枚举类型的一个实例,这些枚举类型成员都默认被final、public、static修饰,所以当使用枚举类型成员时直接使用枚举类型名称调用枚举类型成员即可。由于枚举类型对象继承于java. lang. Enum类,所以该类中一些操作枚举类型的方法都可以应用到枚举类型中。

1.values():将枚举类型成员以数组的形式返回。


public class ShowEnum {enum Constants { // 将常量放置在枚举类型中Constants_A, Constants_B, Constants_C, Constants_D}// 循环由values()方法返回的数组public static void main(String[] args) {Constants enumArray[] = Constants.values();//values()方法返回枚举数组for (int i = 0; i < enumArray.length; i++) {// 将枚举成员变量打印System.out.println("枚举类型成员变量:" + enumArray[i]);}}}

​​​​​​​

2.valueOf()与compareTo()

枚举类型中静态方法valueOft)可以将普通字符串转换为枚举类型,而compareTo(万房)较两个枚举类型成员定义时的顺序。调用compareTo(方法时,如果方法中参数在调用该方法对象位置之前,则返回正整数;如果两个互相比较的枚举成员的位置相同,则返回0;如参数在调用该方法的枚举对象位置之后,则返回负整数.


enum Constants {  //将常量放在枚举类型中Constants_A,Constants_B,Constants_C,Constants_D
}
public class EnumMethodTest { //定义比较枚举类型方法,参数类型为枚举类型public static void compare(Constants c) {Constants array[] = Constants.values();//根据values()方法返回的数组 //将比较结果返回for (int i =0;i < array.length;i++) {System.out.println(c + "与" + array[i] + "的比较结果为:" + c.compareTo(array[i]));}}  //在主方法中调用compare()方法public static void main(String[] args) {compare(Constants.valueOf("Constants_B"));// TODO Auto-generated method stub}}

 3.ordinal():

获取枚举对象的位置索引值。

package com.imooc.weather;public class EnumIndexTest {enum Constants2{//将常量放置在枚举类型中Constants_A,Constants_B,Constants_C}public static void main(String[] args) {for(int i = 0;i < Constants2.values().length; i++) {//在循环中获取枚举类型成员的索引位置System.out.println(Constants2.values()[i] +"在枚举类型中位置索引值"+Constants2.values()[i].ordinal());}}
}

package com.imooc.weather;public class EnumIndexTest {enum Constants2{//将常量放置在枚举类型中Constants_A,Constants_B,Constants_C}public static void main(String[] args) {Constants2[] arrayCon = Constants2.values();for(int i = 0;i < Constants2.values().length; i++) {//在循环中获取枚举类型成员的索引位置System.out.println(arrayCon[i]+"在枚举类型中位置索引值"+arrayCon[i].ordinal());}}
}

11.1.3 使用枚举类型的优势

(1)类型安全.

(2)紧凑有效的数据定义.

(3)可以和程序其他部分完美交互.

(4)运行效率高.

11.2 泛型

11.2.1 回顾 “ 向上转型 ” 和 “ 向下转型 ”

public class Test {
private Object b;   //定义Object类型成员变量
public Object getB() {  //设置相应的getxxx()方法return b;
}public void setB(Object b) {  //设置相应的setxxx()方法this.b = b;}public static void main(String[] args) {// TODO Auto-generated method stubTest t = new Test();t.setB(new Boolean(true));  //向上转型操作System.out.println(t.getB());t.setB(new Float(12.3));Float f = (Float) (t.getB()); //向下转型操作System.out.println(f);}}

在本实例中,Test类中定义了私有的成员变量b 它的类型为Object类型,同时为其定义了相应 
的setXXX0与getXXX0方法。在类主方法中,将nev wBoolean(true)对象作为setBO方法的参数,由于 setB0方法的参数类型为Object,这样就实现了“向上转型”操作。同时在调用getB0方法时,将 getBO方法返回的 Object 对象以相应的类型返回,这个就是“向下转型”操作,问题通常就会出现在这里。因为"向上转型"是安全的,而如果进行"向下转型"操作时用错了类型,或者并没有执行该操作,就会出现异常.例如以下代码:

t.setB(new Float(12.3));

Integer f=(Integer) (t.getB());

System.out.println(f);

改代码并不存在语法错误,可以被编译器接受,但在执行时会出现ClassCastException异常.这样看来."向下转型"操作通常会出现问题,而泛型机制有效地解决了这一问题.

11.2.2 定义泛型类

Object类为最上层的父类,很多程序员为了使程序更为通用,设计程序时通常使传入的值与返回的值都以Object类型为主。当需要使用这些实例时,必须正确地将该实例转换为原来的类型,否则在运行时将会发生ClassCastException异常。

泛型机制,语法如下

类名<T> (T表示一个类型名称)

public class OverClass<T> { //定义泛型类
private T over;  // 定义泛型成员变量
public T getOver() { //设置getXXX()方法return over;
}
public void setOver(T over) {  //设置getXXX()方法this.over = over;
}
public static void main(String[] args) {
//实例化一个Boolean型对象
OverClass<Boolean> Over1 = new OverClass<Boolean>();
//实例化一个Float型对象
OverClass<Float> Over1 = new OverClass<Float>();
Over1.setOver(true);
Over1.setOver(12.3f);
Boolean b = over1.getOver();  //不需要进行类型转换
Float f = over2.getOver();
System.out.println(b);
System.out.println(f);

注:在定义泛型类时,一般类型名称使用T来表示,而容器的元素使用E来表达.

11.2.3 泛型的常规用法

1  在定义泛型类时,可以声明多个类型。

Class<T1,T2>
Class:泛型类名称

 2.定义泛型类时声明数组类型

public class ArrayClass<T> {private T[] array; // 定义泛型数组    public T[] getArray() { // 获取成员数组return array;}public void SetArray(T[] array) { // 设置SetXXX()方法为成员数组赋值this.array = array;}public static void main(String[] args) {ArrayClass<String> a = new ArrayClass<String>();String[] array = { "成员1", "成员2", "成员3", "成员4", "成员5" };a.SetArray(array); // 调用SetT()方法for (int i = 0; i < a.getArray().length; i++) {System.out.println(a.getArray()[i]); // 调用getT()方法返回数组中的值}}}

3.集合类声明容器的元素  

import java.util.HashMap;import java.util.Map;public class MutiOverClass<K, V> {public Map<K, V> m = new HashMap<K, V>(); // 定义一个集合HashMap实例// 设置put()方法,将对应的键值与键名存入集合对象中public void put(K k, V v) {m.put(k, v);}public V get(K k) { // 根据键名获取键值return m.get(k);}public static void main(String[] args) {// 实例化泛型类对象
MutiOverClass<Integer, String> mu = new MutiOverClass<Integer, String>();for (int i = 0; i < 5; i++) {// 根据集合的长度循环将键名与具体值放入集合中mu.put(i, "我是集合成员" + i);}for (int i = 0; i < mu.m.size(); i++) {// 调用get()方法获取集合中的值System.out.println(mu.get(i));}}
}

其实在例11.9中定义的泛型类&nbspMutiOverClass&nbsp纯属多余,因为在Java中这些集合框架已经都被泛发化了,可以在主方法中直接使用public Map<K、V>m=&nbspnewHashMap&nbsp<K.V>0;语句创建实例。然后题的用Map接口中的put()与get(方法完成填充容器或根据键名获取集合中具体值的功能,集合中需Hash Map这种集合类型之外,还包括Array List、Vector等。

import java.util.*;
public class ListClass {public static void main(String[] args) {// 定义ArrayList容器,设置容器内的值类型为IntegerList<Integer> a = new ArrayList<Integer>();a.add(1); // 为容器添加新值for (int i = 0; i < a.size(); i++) {// 根据容器的长度循环显示容器内的值System.out.println("获取ArrayList容器的值:" + a.get(i));}// 定义HashMap容器,设置容器的键名与键值类型分别为Integer与String型Map<Integer, String> m = new HashMap<Integer, String>();for (int i = 0; i < 5; i++) {m.put(i, "成员" + i); // 为容器填充键名与键值}for (int i = 0; i < m.size(); i++) {// 根据键名获取键值System.out.println("获取Map容器的值" + m.get(i));}// 定义Set容器,使容器中的内容为String型Set<Character> Set= new HashSet<>();Set.add('一');Set.add('二');for(Character c : Set) {System.out.println("获取Set容器的值 " + c );}}}

11.2.4 泛型的高级用法

泛型的高级用法主要包括通过类型参数T的继承和通过类型统配符的继承来限制泛型类型.

1.通过类型参数T的继承限制泛型类型

默认可以使用任何类型来实例化一个泛型类对象,但Java中也对泛型类实例的类型作了限制,这主要通过对类型参数T实现继承来体现。

class 类名称 <T extends anyClass>

anyClass:接口或者类

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Limitclass<T extends List> {//限制泛型的类型
public static void main (string[] args) {//可以实例化已经实现List接口的类
Limitclass<ArrayList> 11 = new LimitClass<ArrayList>();
Limitclass<LinkedList>12 = new Limitclass<LinkedList>();
//这句是错误的,因为HashMap没有实List()接口
//LimitClass<HashMap> 13=new Limitclass<HashMap>();

上面代码中,将泛型作了限制,设置泛型类型必须实现List接口。例如,ArrayList和 LinkedList 都实现了List接口,而HashMap没有实现List接口,所以在这里不能实例化 HashMap类型的泛型对象。
当没有使用extends关键字限制泛型类型时,默认 Object类下的所有子类都可以实例化泛型类对象。如图11.11所示的两个语句是等价的。

2.通过类型通配符的继承限制泛型类型

在泛型机制中,提供了类型通配符,其主要作用是在创建一个泛型类对象时,限制这个泛型类的类型,或者限制这个泛型类型必须继承某个接口或某个类(或其子类)。要声明这样一个对象可以使用“?”通配符,同时使用extends 关键字来对泛型加以限制。

说明:
通过对类型参数T实现继承限制泛型类型时,在声明时就进行了限制,而通过对类型通配符实现继承限制泛型类型时,则在实例化时才进行限制。

使用泛型类型通配符的语法如下:

泛型类名称<?extends List> a=null;

其中,<? extends List>表示类型未知,当需要使用该泛型对象时,可以单独实例化。例如,在项目中创建一个类文件,在该类中限制泛型类型。

A<?extends List> a=null;
a=new A<ArrayList> ();
a=new A<LinkedList>();

如果实例化没有实现List 接口的泛型对象,编译器将会报错。例如,实例化HashMap对象时,编译器将会报错,因为 HashMap类没有实现List 接口。
除了可以实例化一个限制泛型类型的实例之外,还可以将该实例放置在方法的参数中。例如,在项目中创建一个类文件,在该类的方法参数中使用匹配字符串。

public void doSomething(A<? extends List> a){
}

在上述代码中,定义方式有效地限制了传入doSomething()方法的参数类型。
如果使用A<?>这种形式实例化泛型类对象,则默认表示可以将A指定为实例化Object 及以下的子类类型。读者可能对这种编码类型有些疑惑,下面的代码将直观地介绍A<?>泛型机制。

import java.util.*;public class WildClass {public static void main(String[] args) {// TODO Auto-generated method stubList<String> l1 = new ArrayList<String>();  //创建一个ArrayList对象
l1.add("成员"); //在集合中添加内容
List<?> l2 = l1;  //使用通配符
List<?> l3 = new LinkedList<Integer>();
System.out.println("l1:" +l1.get(0)); //获取l1集合中第一个值
System.out.println("l2:" +l2.get(0)); //获取l2集合中第一个值
l1.set(0, "成员改变"); //使用通配符的对象不能调用set()方法
//l2.add("添加");    //使用通配符的对象不能调用add方法
// l2.set(0,"成员改变"); //使用通配符的对象不能调用set方法
//13.add(1);
//13.set(0,1);
System.out.println("l1:" +l1.get(0));}}

3.继承泛型类与实现泛型接口
定义为泛型的类和接口也可以被继承与实现。
例如,在项目中创建一个类文件,在该类中继承泛型类。

public class Extendclass<T1>{
}
class Subclass<T1,T2,T3> extends ExtendClass<T1>{//泛型可以比父类多,但不可以比父
类少
}

如果在SubClass类继承ExtendClass类时保留父类的泛型类型,需要在继承时指明,如果没有指明,直接使用extends ExtendsClass语句进行继承操作,则SubClass类中的T1、T2和T3都会自动变为Object,所以在一般情况下都将父类的泛型类型保留。
定义的泛型接口也可以被实现。
例如,在项目中创建一个类文件,在该类中实现泛型接口。interface TestInterface<T1>{
}
class SubClass2<T1,T2,T3> implements TestInterface<T1>{
}

11.2.5 泛型总结

使用泛型需遵循以下原则。
(1 )泛型的类型参数只能是类类型,不可以是简单类型,如A<int>这种泛型定义就是错误的,

(2)泛型的类型个数可以是多个.
(3 )可以使用extends关键字限制泛型的类型。

( 4)可以使用通配符限制泛型的类型。

11.3 小结

枚举类型中的构造方法

package com.imooc.weather;public class EnumConTest {enum Constants2{//将常量放置在枚举类型中Constants_A("我是枚举成员A"),Constants_B("我是枚举成员B"),Constants_C("我是枚举成员C"),Constants_D(3);private String description;private int i = 4;private Constants2(String description) {this.description = description;}private Constants2(int i) {this.i = this.i + i;}public String getDescription() {return description;}public int getI() {return i;}}public static void main(String[] args) {Constants2 array[] = Constants2.values();for(int i = 0; i < array.length; i++) {System.out.println(array[i]+ "调用getDescription()方法为: " + array[i].getDescription());}Constants2 c2 = Constants2.valueOf("Constants_D");       System.out.println(c2 + "调用getI()方法为"+c2.getI());}
}

Java第十一章总结 枚举与泛型相关推荐

  1. Java 第十一章总结 枚举与泛型

    11.1 枚举 (1) 使用枚举类型设置常量 在项目中创建Constants接口,在接口中定义常量的常规方式. public interface Constants{ public static fi ...

  2. 速学堂(java)第十一章编程题答案(自写)

    速学堂(java)第十一章编程题答案(自写) 1.设计一个多线程的程序如下:设计一个火车售票模拟程序.假如火车站要有100张火车票要卖出,现在有5个售票点同时售票,用5个线程模拟这5个售票点的售票情况 ...

  3. java 第十一章总结

    加载驱动 try{Class.forName("com.mysql.jdbc.Driver");}catch(Exception e){} 连接数据库 Connection get ...

  4. 《JAVA编程思想》学习笔记:第19章(枚举)

    目录 Java编程思想(一)第1~4章:概述 Java编程思想(二)第5章:初始化和清理 Java编程思想(三)第6章:访问权限 Java编程思想(四)第7章:复用类 Java编程思想(五)第8章:多 ...

  5. java语言仅支持单重继承_java语言程序设计基础篇习题_复习题_第十一章

    java语言程序设计基础篇习题_复习题_第十一章 11.1 下面说法是真是假?一个子类是父类的子集. 11.2 使用什么关键字来定义一个子类 11.3 什么是单一继承?什么是多重继承?java支持多重 ...

  6. 【Java数据结构与算法】第十一章 顺序存储二叉树、线索二叉树和堆

    第十一章 顺序存储二叉树.线索化二叉树.大顶堆.小顶堆和堆排序 文章目录 第十一章 顺序存储二叉树.线索化二叉树.大顶堆.小顶堆和堆排序 一.顺序存储二叉树 1.介绍 2.代码实现 二.线索二叉树 1 ...

  7. 【JAVA SE】第十一章 正则表达式、包装类和BigDecimal

    第十一章 正则表达式.包装类和BigDecimal 文章目录 第十一章 正则表达式.包装类和BigDecimal 一.正则表达式 二.包装类 1.概述 2.装箱与拆箱: 3.基本数据和包装类之间的转换 ...

  8. Java语言程序设计(基础篇) 第十一章 继承和多态

    第十一章 继承和多态 11.1 引言 面向对象的编程允许你从已经存在的类中定义新的类,这称为继承. 11.2 父类和子类 1.继承使得你可以定义一个通用的类(既父类),之后扩充该类为一个更加特定的类( ...

  9. java 枚举与泛型_Java枚举和泛型

    这件事让我困扰了一段时间.以前我曾问过 questions,可能是一个不好的措辞和一个太抽象的例子.所以不清楚我实际在问什么.我会再尝试.请不要跳过结论.我期待这个问题根本不容易回答! 为什么我不能在 ...

  10. 《啊哈算法》的Java现实 | 第三章:枚举!很暴力

    <啊哈算法>的Java现实 | 第一章:排序. <啊哈算法>的Java现实 | 第二章:栈.队列.链表. <啊哈算法>的Java现实 | 第三章:枚举!很暴力. & ...

最新文章

  1. 概率论中伯努利分布(bernoulli distribution)介绍及C++11中std::bernoulli_distribution的使用
  2. Java集合篇:LinkedList源码分析
  3. 2016年,我的和自己谈谈
  4. @PostConstruct 注解没有初始化
  5. 1、使用Keras构建图像分类器
  6. Python里面这些点,据说80%的新手都会一脸懵逼
  7. UVALive 4490 Help Bubu
  8. Laraval-admin 自定义form组件
  9. 在unity中,模型自动旋转
  10. Android--语音识别
  11. vce数学考试能用计算机,准备VCE数学考试的诀窍,从一本出色的笔记开始!
  12. 嵌入式MQTT连接主要流程
  13. linux环境搭建篇-redis设置密码
  14. rt3070网卡 linux驱动,移植rt3070芯片网卡驱动到dm365全过程---yingru
  15. android 隐藏虚拟键盘,android隐藏全面屏虚拟键盘实现
  16. 小数点怎么进行进制转换?
  17. Spring?Spring?Spring到底是啥?
  18. 股票基金实时行情监视小程序(C# wpf)
  19. JAVA事务回滚的使用方法
  20. 智能计算机怎么玩游戏,智能电视玩电脑游戏攻略分享

热门文章

  1. 使用XINCheck文档查重软件对本地文档查重
  2. 原生Android开发自学过程(一)
  3. php打开后自动关闭,蜂窝数据打开了又自动关闭怎么办
  4. 前端网页打印window.print()
  5. 2019上半年软考 | 报名时间汇总(持续更新中)
  6. 华中科技大学计算机二级成绩,华中科技大学2017年计算机水平测试(软考)报名通知...
  7. 氮化镓 服务器电源管理系统报价,氮化镓(GaN)技术推动电源管理不断革新
  8. no matching function for call to ‘cv2eigen‘
  9. 千人虚拟社交体验,多人元宇宙场景真的可行么?
  10. Infomages: Embedding Data into Thematic Images