黑马程序员——Java高新技术——JDK4.5版本新特性枚举、高级for循环、静态导入、可变参数、基本数据类型的自动装箱与拆箱

来源:互联网 发布:one note mac 编辑:程序博客网 时间:2024/05/16 15:09

----------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -----------

                   JDK1.5的新特性——枚举类型

 

一、枚举基本使用

1J2SE5.0中新增了枚举类型,用户可以使用该功能取代以往常量定义的方式,同时枚举类型还赋予程序在编译时检查的功能。

在学习使用枚举类型之前用户通常将常量放置在接口中,以便于在程序中能够直接使用,并且该常量不能被修改,因为在接口中定义该常量时,该常量的修饰符为finalstatic

常规定义常量:

public interface Constants{
public static final int Con_stants_A=1;
public static final int Con_stants_B=12;
}

JDK1.5版本新增枚举类型后,枚举类型就逐渐取代了这种常量定义方式。

使用枚举类型定义常量:

public enum Constants{
Contants_A,
Contants_B,
Constants_C
}

其中,enum是定义枚举类型的关键字。

当需要在程序中使用该常量时,可以使用Constants.Constants_A来表示。

2、好处:在编译时期就会发现错误,表明值不符合,减少了运行时期的错误。

3、枚举类是一个class,而且是一个不可被继承的final类,其中的元素都是类静态常量

    4、常用方法:

     构造器:

        1)构造器只是在构造枚举值的时候被调用。

        2)构造器只有私有private,绝不允许有public构造器。这样可以保证外部代码无法重新构造枚举类的实例。因为枚举值是public static final的常量,但是枚举类的方法和数据域是可以被外部访问的。

        3)构造器可以有多个,调用哪个即初始化相应的值。

  例如:


   enum枚举类型名称{

Constants_A("枚举成员A"),
Constants_B("枚举成员B"),
Constants_C("枚举成员C"),
Constants_D(3);
private String description;
private Constants2(){
//定义默认构造方法
}
private Constants2(String description)
{
//定义带参数的构造方法,参数类型为字符串型
this.description=description;
}
private Cosntants2(int i){
//定义带参数的构造方法,参数类型为整型
this.i=this.i+i;
}
}


     非静态方法:(所有的枚举类都继承了Enum方法)

        1String toString() ;//返回枚举量的名称

        2int ordinal() ;//返回枚举值在枚举类中的顺序,按定义的顺序排

        3Class getClass() ;//获取对应的类名

        4) String name();//返回此枚举常量的名称,在其枚举声明中对其进行声明。

    静态方法:

        1valueOf(String e) ;//转为对应的枚举对象,即将字符串转为对象,而CompareTo()方法用于比较两个枚举类型对象定义时的顺序。

        2values() ; 枚举类型实例包含一个values()方法,该方法将枚举类型的成员变量实例以数组方式返回,也可以通过该方法获取枚举类型的成员。

5、演示

 

6、枚举类型的优点

     枚举类型提供了一种用户友好的变量定义方法,枚举了某种数据类型所有可能出现的值。

      它的优点表现在:

       1)类型安全

       2)紧凑有效的数据定义

       3)可以和程序其他部分交互

       4)运行效率高

  二、枚举的高级应用

    1、枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。

    2、枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。把枚举中的成员方法或变量等放在枚举元素的前面,编译器报告错误。

    3、带构造方法的枚举

        1)构造方法必须定义成私有的

        2)如果有多个构造方法,该如何选择哪个构造方法?

        3)枚举元素MONMON()的效果一样,都是调用默认的构造方法。

   4、带方法的枚举

演示:

 

说明:  1)类的方法返回的类型可以是本类的类型

        2)类中可定义静态常量,常量的结果就是自己这个类型的实例对象

        3)枚举只有一个成员时,就可以作为一种单例的实现方式。

        4)所有的枚举都继承自java.lang.Enum类。由于Java不支持多继承,所以枚举对象不能再继承其他类。

        5switch语句支持int,char,enum类型。

 

                       高级for循环

1、概述

   Iterator 不好写,1.4版本iterator方法是定义在collection里面的,可是1.5版本后,collection继承了Iterable<E>.这个接口就是将迭代方法抽取出来了。

它不但是把这个方法抽离出来集合框架,提高了扩展性,它还给集合框架提供了新功能就是高级for循环

  查阅api文档,

public ingerface Iterable<T>

实现这个接口允许对象成为“foreach”语句的目标。

 2、格式

  高级for循环

格式

For(数据类型 变量名:被遍历的集合(Collection)或者数组)

示例:

假如al是一个ArrayList集合,那么代码

 ForString s : al//这个s第一次就指向了al的第一个元素“abc1”,并变化

{System.out.println(s)};

3、高级for循环的局限性

  高级for循环的局限性:不能对集合中的元素做修改动作。

而迭代器:至少还有remove可以用。而如果使用列表迭代器,增删改查都可以使用。

总结:

对集合进行遍历,只能获取集合元素,但是不能对集合进行过多操作

迭代器:除了遍历,还可以进行remove集合中元素的动作,原集合改变。

如果使用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。

   4、高级for循环和传统for循环的区别:

        高级for有一个局限性:必须有被遍历的目标。

例如:我们把hello world打印100次,就只能使用传统for循环。

建议在遍历数组的时候,还是希望使用传统for循环。因为传统for循环可以定义角标。

          问题:

HashMap<Integer,String> hm=new HashMap<Integer,String>();

hm.put(1,a)

hm.put(2,b)

hm.put(3,c)

我想把hm里面的元素都取出来,用高级for如何实现。

一种方式:

Set<Integer> keySet=hm.keySet();

for(integer i:keySet)

{

System.out.println(i+::+hm.get(i));

}

第二种方式:

Set<Map.Entry<integer,String>> keySet=hm.entrySet();

for(Map.Entry<integer,String> me:entrySet)

简写

for(Map.Entry<Integer,String> me:hm.entrySet())

{

System.out.println(me.getKey()+-----+me.getValue());

}

但是如果集合里面没有定义泛型,不能使用for循环,很简单,都不知道什么类型,如何定义类型引用呢?详解在可变参数介绍中。

                            可变参数

  一、概述

        可变参数:其实就是上一种数组参数的简写方式,不用每一次都手动建立数组对象。只要将要操作的元素作为参数传递即可。隐式将这些参数封装成数组。由虚拟机完成。

想传几个参数,就定义为几个元素的数组。不传,视为长度为0的数组。

   二、优点:简化开发代码,提高开发速度。

方法的可变参数:在使用时要注意,可变参数一定要定义在参数列表最后面。

三、代码演示

      传统的方法:

 class ParamMethodDemo

{

  public static void main(String[]args)

  {

      show(3,4);

  }

  public static void show(int a,int b)

  {

   System.out.println(a+,+b);

  }

  public static void show(int a,int b,int c)

 {.....}

}

简单点的

  public static void show(int []arr)

{}

新特性是这样的。

public static void show(int...arr)

{

 System.out.println(arr);

}

注意:当方法中有多个参数时,虚拟机会先把前面的匹配完,剩下的都给后面的了。

举例:

public static void show(String str,int...arr)

{

  System.out.println(arr.length); 

}

public static void main(String[]args)

{

show(hha,2,3,4,5);

}

编译通过,结果是 

                                                  

                            静态导入

一、概述

    Jdk1.5版本的新特性。StaticImport 静态导入,用来导入静态工具类

   举例:  

improt java.util.*;

import static  java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。

需求:

improt java.util.*;
class StaticImport
{
public static void main(String[]args)
{
int[]arr={3,1,5}
Arrays.sort(arr);
int index=Arrays.binarySearch(arr,1)
System.out.println(Arrays.toString(arr));
System.out.println("Index="+index);
}
}

我们每次写工具类的时候,都要写类名.

如果不导入包,我们还要写  java.util.Arrays.sort(arr);导入包后,就不需要写包。

那么如果,我们把工具类Arrays导入的话,我们是不是就不用写类名.了?

因为它没有对象。不需要对象,就不需要特有数据啊。

静态导入:

Improt java.util.*;

importStatic  java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。

接下来,我们就不需要写Arrays.

import java.util.*;
import static java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。
//接下来,我们就不需要写Arrays.
class StaticImport
{
public static void main(String[]args)
{
int[]arr={3,1,5}
sort(arr);
int index=binarySearch(arr,1)
System.out.println(Arrays.toString(arr));
System.out.println("Index="+index);
}
}

运行ok

接下来,我们把  System.out.println(Arrays.toString(arr));这条语句中的Arrays.也去掉,

编译,失败

  无法将java.lang.object中的toString()应用于int[]

为什么呢?

因为我们知道class StaticImport 这个类首先继承的是Object类。它会认为,使用的是Object类中的toString方法。而Object类中的toString方法是没有参数的。

2、注意事项   

当类名重名时,需要制定具体的包名。

当方法重名时,要指定具备所属的对象或者类。    

 

 

                     基本数据类型的自动拆箱与装箱

   1、自动装箱:Integer iObject = 3;

   2、自动拆箱:iObject + 2;

   3、对于基本数据类型的说明:整数在-128 ~ 127之间的数,包装成Integer类型对象,会存入常量池中的缓存,再创建一个对象的时候,如果其值在这个范围内,就会直接到常量池中寻找,因为这些小数值使用的频率很高,所以缓存到常量池中,被调用时就方便很多。

  4、享元模式:

        1)概述:有很多个小的对象,他们有很多相同的属性,把属性相同的部分变为同一个对象,这些属性称为内部状态。那些不同的属性,把他们变成方法的参数,称之为外部的状态。这种优化内存,只创建一个对象的模式,称之为享元模式。例如:Integer对象中对象取值范围在-128~127时,其值相同的对象想等,因为这些小的数被缓存在一个池中,被调用的频率较高,所以通常在池中取,从而导致对象相同。这就是典型的享元设计模式。

        2)应用:

          (1word中输入英文字母,可创建26对象,每个对象值是出现的位置不同(坐标),所以可用一个对象调用位置的方法:如,字母ii.display(intx,inty),将高度重复使用的char类型的字母i封装成一个对象使用。

          (2)图标:window下的文件夹图标,只有名称这个属性不同,包含了很多其他相同的属性,那么可以应用享元模式。

           3valueOf(int x)Integer中静态方法,将一个整数转换为Integer,即把基本数据类型变为包装类。


-----------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -----------

0 0