JAVA学习-Java新特性(泛型、枚举、Annotation)

所谓的Java新特性现在都是指从JDK 1.5之后开始的,例如,在前面已经学习过两个新特性:switch支持String判断(JDK 1.7提供的)、自动装箱和拆箱、可变参数、foreach、静态导入、泛型、枚举、Annotation。

对于所有的新特性,我的个人建议:有些新特性你今天一定是不知道怎么用的,我们今天只是来看一下这些语法,至于使用方面,慢慢来观察。

1、可变参数(理解)

如果说现在有这样一个要求,要求实现整数的加法操作,并且方法可以接收任意多个整型数据一起实现加法操作。

如果按照传统的思路,现在的实现方式可以采用数组作为参数的类型。


package cn.mldn.demo;

public class TestDemo {

public static void main(String[] args) {

System.out.println(add(new int[] { 1, 2 }));

System.out.println(add(new int[] { 1, 2, 3 }));

}

public static int add(int data[]) {

int sum = 0 ;

for (int x = 0; x < data.length; x++) {

sum += data[x] ;

}

return sum ;

}

}

此处使用数组完全属于无奈,因为现阶段只能够通过数组传递多个数据。但是本操作虽然实现了功能,可是在调用形式上有问题,题目的本身要求:可以接收任意多个整型数据,每一个数据之间应该使用“,”分隔才最合适。所以为了解决这种传递任意参数的问题,从JDK 1.5之后增加了可变参数方法的定义。


[public | protected | private] [final] [static] 返回值类型方法名称(参数类型 ... 参数名称) [throws 异常,异常, ..] {

[return [返回值] ;]

}

虽然可变参数的语法形式上有些别扭,但是把它按照数组一样理解。

范例:使用可变参数


package cn.mldn.demo;

public class TestDemo {

public static void main(String[] args) {

System.out.println(add(new int[] { 1, 2 }));

System.out.println(add(new int[] { 1, 2, 3 }));

System.out.println(add(1, 2, 3));

}

public static int add(int ... data) {   // 可变参数

int sum = 0 ;

for (int x = 0; x < data.length; x++) {

sum += data[x] ;

}

return sum ;

}

}

可变参数最大的好处在于方法调用时,可以随意编写参数进行数据的传递,但是此类操作只会在系统类库的学习中遇见,你们自己写的代码,先别用。

2、foreach输出(理解)

如果说现在有一个数组要想实现数据的输出,一定使用for循环完成。

范例:使用for循环输出数组


package cn.mldn.demo;

public class TestDemo {

public static void main(String[] args) {

int data[] = new int[] { 1, 2, 3 };

for (int x = 0; x < data.length; x++) {

System.out.println(data[x]);

}

}

}

而从JDK 1.5之后增加了一类新的输出结构


for(数据类型 变量 : 数组|集合) {

// 操作代码

}

本程序的意思是根据数组的长度进行循环操作,并且每次循环的时候依次取出数组之中的每一个元素,将其赋值给声明的变量。

范例:使用foreach输出


package cn.mldn.demo;

public class TestDemo {

public static void main(String[] args) {

int data[] = new int[] { 1, 2, 3 };

for (int x : data) {    // 循环次数由数组长度定义

System.out.println(x);  // 每一个内容不再根据下标取得了

}

}

}

此类操作在初学的时候不建议使用,因为你们要习惯下标问题。

3、静态导入(没用,都不知道有什么用)

首先来观察这样一种情况,如果说现在有一个类,这个类里面的方法全部是static方法。

范例:定义MyMath类


package cn.mldn.util;

public class MyMath {

public static int add(int x, int y) {

return x + y;

}

public static int sub(int x, int y) {

return x - y;

}

}

如果在传统情况下,要使用以上类之中所定义的方法,应该先导入包.类,而后通过类名称调用。


package cn.mldn.demo;

import cn.mldn.util.MyMath;

public class TestDemo {

public static void main(String[] args) {

System.out.println(MyMath.add(10, 20));

System.out.println(MyMath.sub(30, 20));

}

}

但是有一部分人群就有疑问。在之前学习过,如果在主类中定义的方法,并且由主方法直接调用的话,则方法上必须加上static,那么能不能把以上导入包中的static方法不使用类名称而直接调用呢(相当于将方法定义在主类之中)。

范例:静态导入


package cn.mldn.demo;

import static cn.mldn.util.MyMath.*;

public class TestDemo {

public static void main(String[] args) {

System.out.println(add(10, 20));

System.out.println(sub(30, 20));

}

}

此时调用的方法不再加入类名称,那么就好比这些方法直接在主类中定义一样。

4、泛型(理解)

此部分的内容你先听明白,不要去思考怎么用。因为用起来没这么麻烦。

4.1、泛型的引出

例如,现在要求用户设计一个表示坐标点的类,但是此坐标保存数据有可能有如下几种:

· 整型数据:x = 10、y = 20;

· 小数数据:x = 10.2、y = 20.3;

· 字符串数据:x = 东经100度、y = 北纬20度。

那么现在很明显,Point类表示坐标,那么针对于坐标点有三类数据,而在Point类里面应该定义有两个属性:x、y,所以现在首先要解决的问题就是确定出x、y属性的数据类型。

既然现在要保存有int、double、String或者以后有可能的其它类型,则自然想到使用Object,因为存在如下转换关系:

· 保存整型:int è 自动装箱为Integer è 向上转型为Object;

· 保存小数:double è 自动装箱为Double è 向上转型为Object;

· 保存字符串:String è 向上转型为Object。

范例:实现代码


class Point {

private Object x ;

private Object y ;

public void setX(Object x) {

this.x = x;

}

public void setY(Object y) {

this.y = y;

}

public Object getX() {

return x;

}

public Object getY() {

return y;

}

}

范例:保存int型数据


public class TestDemo {

public static void main(String[] args) {

// 第一层次:设置坐标数据

Point point = new Point() ;

point.setX(10); // 向上转型为Object

point.setY(20); // 向上转型为Object

// 第二层次:取得坐标数据

int x = (Integer) point.getX() ;    // 向下转型

int y = (Integer) point.getY() ;    // 向下转型

System.out.println("x = " + x + ",y = " + y);

}

}

范例:保存double型数据


public class TestDemo {

public static void main(String[] args) {

// 第一层次:设置坐标数据

Point point = new Point() ;

point.setX(10.2);   // 向上转型为Object

point.setY(20.3);   // 向上转型为Object

// 第二层次:取得坐标数据

double x = (Double) point.getX() ;  // 向下转型

double y = (Double) point.getY() ;  // 向下转型

System.out.println("x = " + x + ",y = " + y);

}

}

范例:保存String型数据


public class TestDemo {

public static void main(String[] args) {

// 第一层次:设置坐标数据

Point point = new Point() ;

point.setX("东经100度"); // 向上转型为Object

point.setY("北纬20度");  // 向上转型为Object

// 第二层次:取得坐标数据

String x = (String) point.getX() ;  // 向下转型

String y = (String) point.getY() ;  // 向下转型

System.out.println("x = " + x + ",y = " + y);

}

}

此时的代码已经很好的完成了给出的系统要求,但是本程序依靠的是Object可以接收所有数据类型这一特征展开的,于是成是Object,败笔也在于次,因为Object保存的范围太大了。那么在程序运行之中就有可能出现隐患。

范例:观察问题


public class TestDemo {

public static void main(String[] args) {

// 第一层次:设置坐标数据

Point point = new Point() ;

point.setX(10); // 向上转型为Object

point.setY("北纬20度");  // 向上转型为Object

// 第二层次:取得坐标数据

String x = (String) point.getX() ;  // 向下转型

String y = (String) point.getY() ;  // 向下转型

System.out.println("x = " + x + ",y = " + y);

}

}

此时程序编译的时候没有任何的错误,但是执行的时候会出现“ClassCastException”,所以来讲此时的程序就存在有安全隐患,事实上,所有对象的向下转型都有可能存在这种安全隐患。最好的做法就是别转型。

以上的问题在JDK 1.5之前根本就无法解决,而在JDK 1.5之后由于引入了泛型的处理机制,所以此类问题很好的解决了。所谓的泛型指的是类之中定义的属性,在程序编译的时候不给出具体的类型,只给出一个类型的占位标记,而后在使用此类产生对象时,再设置具体类型。

范例:利用泛型修改


public class TestDemo {

public static void main(String[] args) {

// 第一层次:设置坐标数据

Point point = new Point() ;

point.setX("东经100度");

point.setY("北纬20度");

// 第二层次:取得坐标数据

String x = point.getX() ;   // 向下转型

String y = point.getY() ;   // 向下转型

System.out.println("x = " + x + ",y = " + y);

}

}

那么此时由于泛型技术的出现,取消了向下转型,而向下转型取消后就相当于消除了所有的ClassCastException这种安全隐患。但是需要注意的是,在设置泛型类型的时候只能够使用引用类型,即:如果要保存的是int或double,应该使用包装类操作。

范例:保存int


public class TestDemo {

public static void main(String[] args) {

// 第一层次:设置坐标数据

Point point = new Point() ;

point.setX(10);

point.setY(20);

// 第二层次:取得坐标数据

int x = point.getX() ;

int y = point.getY() ;

System.out.println("x = " + x + ",y = " + y);

}

}

请把以上的分析理解了,代码可以暂时不会。但是提示一下,为了照顾JDK 1.5之前所编写的代码。为了保证以前的代码没有任何的错误,所以如果在使用泛型标记类的时候没有设置泛型类型,那么会按照Object做默认处理。


public class TestDemo {

public static void main(String[] args) {

// 第一层次:设置坐标数据

Point point = new Point() ;

point.setX(10);

point.setY(20);

// 第二层次:取得坐标数据

int x = (Integer) point.getX() ;

int y = (Integer) point.getY() ;

System.out.println("x = " + x + ",y = " + y);

}

}

这类的情况一直到今天还会继续发生着,所以如果不设置泛型请一定要记住,类型就是Object。

4.2、通配符(次重点)

下面为了方便讲解,重新定义一个使用泛型的类。


class Info {

private T msg ;

public void setMsg(T msg) {

this.msg = msg;

}

public T getMsg() {

return msg;

}

}

下面要针对于Info类的对象实现一次引用传递。


public class TestDemo {

public static void main(String[] args) {

Info info = new Info() ;

info.setMsg("Hello World .");

fun(info) ;

}

public static void fun(Info temp) {

System.out.println(temp.getMsg());

}

}

但是既然是设置泛型,肯定不可能只是String一种,有可能设置其它类型。此时,如果传递的是一个“Info”那么fun()方法是不可能使用的。如果用重载也不可能,因为重载的看重的是数据类型。于是现在发现,泛型一旦使用之后,在之前好不容易解决的参数统一问题,现在又重新回来了。于是这个时候有同学说了,那么既然参数上设置泛型会存在有问题,那么不如就别设置了。但是问题又回来了,如果不设置泛型,那么参数表示的类型就是Object。

范例:参数上不使用泛型


public class TestDemo {

public static void main(String[] args) {

Info info = new Info() ;

info.setMsg("可乐");

fun(info) ;

}

public static void fun(Info temp) {

temp.setMsg(100);   // 现在修改为Integer

System.out.println(temp.getMsg());

}

}

所以这个时候发现,不设置泛型,操作的数据形式就可能出现混乱,于是现在就可以总结出来,我们需要的是一个可以接收任意的泛型类型,但是又不能修改里面数据,并且可以取得里面数据的操作。那么现在就只能够利用通配符“?”来完成此功能。

范例:使用“?”解决


public class TestDemo {

public static void main(String[] args) {

Info info = new Info() ;

info.setMsg("可乐");

fun(info) ;

}

public static void fun(Info

时间: 2024-10-21 19:05:18

JAVA学习-Java新特性(泛型、枚举、Annotation)的相关文章

Java 8的新特性—终极版

声明:本文翻译自Java 8 Features Tutorial – The ULTIMATE Guide,翻译过程中发现并发编程网已经有同学翻译过了:Java 8 特性 – 终极手册,我还是坚持自己翻译了一版(写作驱动学习,加深印象),有些地方参考了该同学的. Java 8 前言: Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章,例如Playing with Java 8 – Lambdas

Atitit..jdk&#160;java&#160;各版本新特性&#160;1.0&#160;1.1&#160;1.2&#160;1.3&#160;1.4&#160;1.5(5.0)&#160;1.6(6.0)&#160;7.0&#160;8.0&#160;9.0&#160;attilax&#160;大总结

Atitit..jdk java 各版本新特性 1.0 1.1 1.2 1.3 1.4 1.5(5.0) 1.6(6.0) 7.0 8.0 9.0 attilax 大总结 1.1. Java的编年史2 1.2. Java版本:JDK 1.02 1.3. Java版本:JDK 1.13 1.4. Java版本:JDK 1.2 (Java 2)4 1.4.1. 1999年5 1.4.2. 2000年5 1.5. Java版本:JDK 1.35 1.5.1. 2001年6 1.5.2. 2002年7

Java 5.0 新特性

package com.fish.jdk15; import java.util.ArrayList; import java.util.Collections; /*  jdk1.5新特性之-------静态导入    静态导入的作用: 简化书写.   静态导入可以作用一个类的所有静态成员(静态方法和静态成员变量).     静态导入的格式:  import static 包名.类名.静态的成员:     静态导入要注意的事项:   1. 如果静态导入的成员与本类的成员存在同名的情况下,那么默

Java SE 6 新特性: JMX 与系统管理

Java SE 6 新特性: JMX 与系统管理 2006 年底,Sun 公司发布了 Java Standard Edition 6(Java SE 6)的最终正式版,代号 Mustang(野马).跟 Tiger(Java SE 5)相比,Mustang 在性能方面有了不错的提升.与 Tiger 在 API 库方面的大幅度加强相比,虽然 Mustang 在 API 库方面的新特性显得不太多,但是也提供了许多实用和方便的功能:在脚本,WebService,XML,编译器 API,数据库,JMX,网

Java SE 6 新特性: 编译器 API

新 API 功能简介 JDK 6 提供了在运行时调用编译器的 API,后面我们将假设把此 API 应用在 JSP 技术中.在传统的 JSP 技术中,服务器处理 JSP 通常需要进行下面 6 个步骤: 分析 JSP 代码: 生成 Java 代码: 将 Java 代码写入存储器: 启动另外一个进程并运行编译器编译 Java 代码: 将类文件写入存储器: 服务器读入类文件并运行: 但如果采用运行时编译,可以同时简化步骤 4 和 5,节约新进程的开销和写入存储器的输出开销,提高系统效率.实际上,在 JD

Java 8 新特性:Java 类库的新特性之 Stream类 ——诺诺&quot;涂鸦&quot;记忆

----------   诺诺学习技术交流博客.期待与您交流!    ---------- 详情请查看:http://blog.csdn.net/sun_promise  Java 类库的新特性之 Stream类 (注:此文中涉及到的一部分图片为网络图片,若有问题,请联系我将其删除.) 一.Java8对IO/NIO 的改进 Java 8 对 IO/NIO 也做了一些改进,主要包括: 改进了java.nio.charset.Charset 的实现,使编码和解码的效率得以提升: 精简了jre/lib

Java 8 新特性:Java 类库的新特性之 Optional类 ——诺诺&quot;涂鸦&quot;记忆

----------   诺诺学习技术交流博客.期待与您交流!    ---------- 详情请查看:http://blog.csdn.net/sun_promise  Java 类库的新特性之 Optional类 1.Optional简述 到目前为止,著名的NullPointerException是导致Java应用程序失败的最常见原因.过去,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的

Java 9和Java 10的新特性

http://www.infoq.com/cn/news/2014/09/java9 Java 9新特性汇总 继2014年3月份Java 8发布之后,Open JDK加快了开发速度, Java 9的发布已经提上日程.预计在2016年发布Java 9,同时公布了JEP(JDK改进提议)中的前期列表.任职于Takipi 的Alex Zhitnitsky整理了Java 9中一些纳入JSR(Java规范提案)的新特性和大家一直期待但未确定的一些特性.这些特性有Jigsaw项目.新的智能编译工具.期待已久

Java SE 6 新特性: HTTP 增强--转

概述 Java 语言从诞生的那天起,就非常注重网络编程方面的应用.随着互联网应用的飞速发展,Java 的基础类库也不断地对网络相关的 API 进行加强和扩展.在 Java SE 6 当中,围绕着 HTTP 协议出现了很多实用的新特性:NTLM 认证提供了一种 Window 平台下较为安全的认证机制:JDK 当中提供了一个轻量级的 HTTP 服务器:提供了较为完善的 HTTP Cookie 管理功能:更为实用的 NetworkInterface:DNS 域名的国际化支持等等. NTLM 认证 不可

Java SE 8 新特性之旅 : Java开发世界的大变动

我很自豪的成为了adopt-OpenJDK的一员,像其他专业团队成员一样,但是我只刚加入了8个月,我们一同经历了Java SE 8 的开发.编译.编码.讨论--等等,直到JDK上线.Java SE 8发布于2014年3月18日,现在可供下载使用. 我很高兴发布这一系列"Java SE 8 新特性之旅",我会写一些例子来简化Java SE 8知识的获取.开发经验.新特性和API,然后 利用你的知识,提高你的编码能力,同时提高你的生产力.我希望你能像我写文章一样享受它. 我们将游览Java