1995.5.23 java语言诞生
sun公司推出java语言的同时,也推出了一系列的开发工具,比如JDK
(java development Kit)
JVM
java API
时间 版本 API 用途
1996 JDK1.0 250 主要用在桌面型应用程序和applet的开发上
1997 JDK1.1 500 图形用户界面编程
1998 JDK1.2 2300 J2SE J2EE J2ME
2000 JDK1.3
2000 JDK1.4
2004 JDK1.5 3500 Tiger 语言本身发生了很大变化
更稳定、更安全、更高效
2005 JDK1.6
2011 JDK1.7
javaSE1.5
java5新特性:
自动装箱/拆箱
增强的for循环
类型安全枚举
可变长参数
静态导入
格式化输出
泛型
Annnotation(注解)
一、Autoboxing/Unboxing
-----------------------------------------------------------------
1.什么是装箱和拆箱操作?
装箱操作:将基本数据类型转换为它所对应的包装器类
拆箱操作:将包装器类转换为对应的基本数据类型
包装器类:
位于java.lang包下
8种基本数据类型 对应的包装器类
byte Byte
short Short
int Integer
long Long
char Character
float Float
double Double
boolean Boolean
包装器类分为两类
1.Number的子类:
Byte、Short、Integer、Long、Float、Double
2.其他类型:
Character、Boolean
Number类
intValue()
doubleValue()
.......
*Value()用于返回该引用类型所代表的基本数据类型
Character
charValue()
Boolean
booleanValue()
2.如何进行装箱和拆箱操作?
int a = 10;
Integer b = null;
b = new Integer(a);
a = b.intValue();
3.自动装箱/拆箱
自动装箱:基本数据类型自动转换为包装器类(int--Integer)
自动拆箱:包装器类自动转换为它所对应的基本数据类型(Integer--int)
4.为什么需要装箱/拆箱操作?
自动装箱/拆箱操作大大简化了基本数据类型和引用类型的使用
5.存在的问题
自动拆箱:
调用*Value()方法,和手动拆箱相同
自动装箱:
不是通过new的方式来进行,通过调用valueOf()方法
缓存池
Integer -127~128
Short -127~128
Long -127~128
Byte 全部缓存
Boolean 全部缓存
Float 都不缓存
Double 都不缓存
Character 只缓存ASCII/Unicode编码<127的字符
二、Enhanced for loop
-------------------------------------------------------------------
对于之前出现的for 循环
for(int i=0;i<10;i++) {
//some operation
}
jdk1.5引入增强的for循环,在很大程度上简化了我们对
数组或集合的遍历
语法:
for(type element:arr) {
System.out.println(element);
}
type:类型,所要遍历的数组或集合里的数据类型
element:元素,遍历时的临时变量
arr:所要遍历的数组或集合的引用
集合必须实现了Iterable接口
Collection继承于Iterable接口
ctrl+shift+o
alt+/ 提示
弊端:
1).增强的for循环本身无法明确的指向元素所在的索引位置
2).需要强制类型转换
三、Type-safe enumeration
-----------------------------------------------------------------
JDK1.5引入一个全新类型的“类”--枚举类型
enum class interface annotation
Why?
定义一个代表星期的类
int weekday=0
引入枚举类型可以控制源程序的非法值,只能是若干
固定值中的一个,如果超出这个范围,编译器在编译时报错。
public class Gender {
private String name;
priavte static final MALE = new Gender("男");
priavte static final FEMALE = new Gender("女");
//public Gender() {}
private Gender(String name) {
this.name = name;
}
public static Gender getInstance(int i) {
switch(i) {
case 0:
return MALE;
case 1:
return FEMALE;
default:
return null;
}
}
//getter setter
}
Gender g1 = Gender.MALE;
Gender g1 = new Gender("男");
Gender g2 = new Gender("女");
Gender g2 = new Gender("不男不女");
What?
1).枚举类型的定义
public enum Gender {
MALE,FEMALE;
}
其中每一个枚举元素都是该枚举类型的一个实例
2).枚举的使用
Gender male = Gender.MALE;
Gender female = Gender.FEMALE;
3).枚举的遍历
每个枚举类型默认都提供了两个静态方法values()和valueOf()方法
for(Gender g:Gender.values()) {
}
values()方法返回的是一个包含该枚举类型当中所有枚举
元素的数组。
valueOf(String name)可以通过枚举元素拿到该枚举类型
的一个实例。
4).Eunm和enum的区别
a>每一个使用enum关键字定义的枚举类型默认都继承
于java.lang.Enum类。
b>枚举类当中的枚举元素都是该枚举类的实例,默认
为public static final修饰的。
Enum类只有一个受保护的构造方法
protected Enum(String name,int ordinal) {}
name:代表枚举元素的名称
ordinal:代表枚举元素的编号,编号从0开始,按照声明
顺序进行编号
name():获取该枚举元素的名称
ordinal():获取该枚举元素在列表中的编号
5)枚举类型的属性和方法
枚举类中可以定义属性和方法。
规则:
必须定义在枚举元素声明之后
6)枚举类型的构造方法
a.构造方法必须定义在元素声明之后
b.构造方法只能是private的,不写默认也是private的
c.元素如果要调用有参构造方法,可以在元素之后加上
“(参数)”
7).枚举继承
枚举类型默认隐式地继承java.lang.Enum类,所以无法再
继承其他类。
8).枚举实现接口
有两种方式:
1.和普通class类一样,在枚举类中实现接口
2.每一个枚举元素分别实现这个接口
9).枚举中的抽象方法
枚举类型中可以定义一个或多个抽象方法,但是每一
枚举元素必须分别实现这些抽象方法
10).switch对枚举的支持
switch(byte)
switch(int)
switch(short)
switch(char)
switch(枚举类型)
red,yellow,green
11).类集对枚举的支持
java.util包下
EnumMap
实现了Map接口,基本操作和Map相同
调用构造方法时,需要指定键值的枚举类型
EnumSet
实现了Set接口
构造方法私有化
其中所有方法都是静态方法,可以通过allOf/of...
方法来实例化EnumSet
四、Variable Arguments
-------------------------------------------------------------------
可变长参数使得我们可以声明一个可接收可变数目参数的方法
public int sum(int a,int b) {
return a+b;
}
public int sum(int a,int b,int c) {
return a+b+c;
}
public int sum(int[] a) {
//对数组进行遍历相加
//必须先声明一个数组
}
int[] a = new int[]{1,2,3,4};
sum(a);
---------------------------------------------
public int sum(int... param) {
//可变参数在处理的时候按照数组的方式进行处理
//不需要声明数组
//直接引用
}
sum(1,2);
sum(2,3,4);
sum();null
在使用可变参数后,在调用方法时可以依据类型传入一个或多个
该类型的参数或者传入一个该类型的数组参数。
使用条件:
//1.如果参数列表中有数组参数,不能再使用可变参数,两者不能够
共存。
2.在一个方法中最多只能定义一个可变参数,并且必须位于参数
列表的最后。
五、static import
-------------------------------------------------------------------
jdk1.5之前,要使用某个类的静态成员,必须给出提供该静态成员
的类。
jdk1.5引入静态导入:可以使被导入类的静态成员在当前类中直接
可见,不需要再提供类名。
import static ........
过度使用会在一定程度上降低代码的可读性。
六、格式化输出(printf)
--------------------------------------------------------------------
C语言中存在
printf("this is %d",10);
java的格式化输出的语法比C更严格
java的格式化输出由java.util.Formatter支持
Formatter
printf风格的格式化字符串的解释程序
主要方法:
format(String format,Object.. args){}
第一个参数:包含格式化说明符的格式化字符串
第二个参数:与格式化说明符对应的可变参数
eg:
format("this is %1$s,%d","test",100);
格式化说明符的语法:
%[argument_index$][flags][width][.precision]conversion
argument_index:代表参数在参数列表中的位置
flags:标志位,用于表示输出格式 eg:-
width:表示参数所占用的宽度
precision:表示整数位数或小数的浮点数
conversion:具体的格式化字符
日期格式化说明符语法:
%[argument_index$][flags][width]conversion
conversion:t/TY tM
String类和PrintStream类也支持格式化输出
String类增加了静态方法format(String format,Object.. args)
PrintStream类增加了printf(String format,Object... args)
七、Generic
---------------------------------------------------------------
泛型的本质是参数化类型,也就是说我们所操作的数据类型可
以被指定为一个参数,该参数可以用在类、接口和方法的创建中,
分别称为泛型类、泛型接口和泛型方法。
Why?
构建一个类,提供属性并打印出属性值
要求属性类型为Integer、String、Boolean......
jdk1.5之前,为了使类具有通用性,通常使用Object去代替其他
类型。
使用Object的缺陷:
1.需要进行强制类型转换
2.容易出现ClassCastException
What?
通过引入泛型,可以保证编译时类型的安全和运行时更小的抛出
ClassCastException的可能。
How?
泛型类:
在声明类的时候,指定泛型类型参数
public class Test<T1,T2> {
private T1 foo;
}
类型参数T可以是任意合法的标识符
一般约定:
T---type
E---element
K---key
V---value
术语:
ArrayList<E>
ArrayList称为该泛型类的原始类型
E为类型参数
<>读作typeof
ArrayList<E>称为ArrayList的泛型类型/参数类型
使用:
在实例化泛型类时,只能传入具体的类类型,不能
是基本数据类型。
泛型类中的属性类型可以根据传入的参数类型确定
不指定参数类型时,默认该类中的属性类型为Object
class Map<K,V>
限制泛型使用类别
当实例化泛型类时,预设可以使用任意类型去实例化
泛型类型中的参数类型,但是如果要限制使用泛型类型时,
只能是某个特定类型或其子类才能实例化该泛型类,这时
可以使用extends关键字指定该参数类型是实现了某个接口
或继承于某个类。
class Generic<T extends Collection> {}
Generic<ArrayList> g = new Generic<ArrayList>();
如果没有使用extends关键字指定类型时,默认是
<T extends Object>
泛型通配声明
泛型通配符?
Generic<String> foo = null;
Generic<Integer> foo1 = null;
foo = new Generic<String>();
foo1 = new Generic<Integer>();
//声明
Generic<? extends Number> foo = null;
foo = new Generic<String>();
foo = new Generic<Integer>();
?:可以匹配任意的类型
? extends 类型:表示该类型为某个特定类型的子类
? super 类型:表示该类型为某个特定类型的父类
使用<?>或<? extends someClass>声明的引用,只能
去获取指定对象的值或清空其值,而不能给他进行赋值操作
SimpleCollection
int[] t;
int index;
add()
int getLength();
get(int i);
泛型继承类别
public class Chid<T> extends Parent<T> {}
子类的类型声明必须和父类的一致
public class Child extends Parent<String>{}
public class Child<T> extends Parent<String>{}
泛型接口
使用和泛型类相同
语法定义:
interface interName<类型参数,类型参数> {}
eg:
public interface Test<T> {
public abstract void fun(T t);
public abstract T fun1();
}
泛型方法:
泛型方法的类型参数必须声明之后才能使用
I).在泛型类中,由于类型参数声明过,直接使用
II).在非泛型类中,需要在返回值前先声明类型参数才能使用
八、Annotation
----------------------------------------------------------------------
JDK1.5引入annotation,annotation提供一些原来不属于源程序
的数据,实际上表示的是一种注释语法,一种标记。
根据所起的作用分为两类:
编译检查:仅作为一个标记给编译器一些信息,让编译器在编译的
时候做一些特殊的处理。
代码处理:运行时通过反射可以获取annotaion的信息并执行相应
的操作
(一)系统内建的Annotation
jdk1.5以后系统内建了三个annotation,他们都是用来做编译检查的
位于java.lang包下
1) @Override
表示重写/覆写操作,强制保证@Override所标识的方法确实是覆写
了父类中同名的方法。
2) @Deprecated
表示过时的、不建议使用的操作。
用法:
a.定义了一个类,不建议使用它
b.在父类中定义了一个Deprecated的方法,子类重写时编译器会
发出警告。
3) @SupprepssWarnings
表示抑制/压制警告,不让编译器发出警告,可以同时抑制多个警告
@SuppressWarnings({ "rawtypes", "unchecked" ,"deprecation"})
unchecked:表示未经检查的操作
deprecation:表示过时的操作
rawtypes:表示泛型
all:所有
@Override @Depracated是Marker Annotation,即名称本身给编译器
提供信息
@SuppressWarnings({"unchecked","rawtypes"})
(二)自定义Annotation的定义和使用
自定义annotation一般都是用来做代码处理的
语法定义:
@interface annotationName {
}
public @interface Override {
}
自定义的Annotation,本质上自动继承了java.lang.annotation.Annotation
接口。
Annotation与接口的异同:
I.Annotation是一个接口
1.变量和接口中一样,只能是public static final的
2.方法和接口中一样,只能是public abstract的
II.Annotation是一个特殊的接口
1.annotation中的方法必须没有参数,不能抛出异常,必须有
返回值,返回值类型有限制
2.可以给方法的返回值设定默认值
3.annotation中的方法称之为属性
4.使用的时候使用标记的形式使用 eg:@MyAnnotation
5.根据保留时间的不同执行不同的操作(高级特性)
Annotation的属性
语法:
type arrName() [default value];
type类型可以是:
基本数据类型
String类型
Class类类型
枚举类型
Annotation类型
以及它们的一维数组形式
Annotation的使用
I.如果属性没有指定默认值,使用时必须给属性赋值
II.如果只有一个属性且属性名称为value时,在使用时可以不指定
属性名称。
III.除了value属性其他属性都有默认值时,在使用时也可以不指定
属性名称。
(三)高级特性---元注解
元注解:用来标识注解的注解
1. @Retention
用来指定annotation的保留范围,其取值由java.lang.annotation.
RetentionPolicy提供。
public enum RetentionPolicy {
SOURCE, //只保留在java源文件中
CLASS, //保留在class文件中,不会被JVM读取,默认
RUNTIME; //保留在运行时(保留在class文件中,运行时被JVM读取)
}
@Retention(RetentionPolicy.CLASS)
public @interface myAnnotation {
}
一个自定义的annotation要想起作用,可以通过反射机制在运行时
获取相应的信息。
java.lang.reflect.AnnotatedElement
//用来判断指定元素上是否有指定类型的annotation存在
public abstract boolean isAnnotationPresent(Class annotationType)
public abstract Annotation getAnnotation(Class annotationType)
public abstract Annotation[] getAnnotations()
2. @Target
用来指定annotation的使用范围,其取值由java.lang.annotation.
ElementType提供
public @interface Target {
ElementType[] value();
}
@Target({ElementType.METHOD,ElementType.FIELD})
public @interfact myAnnotation {
}
public enum ElmenetType {
ANNOTATION_TYPE, //annotation类声明上
CONSTRUCTOR, //构造器上
FIELD, //实例变量上
LOCAL_VARIABLE, //局部变量上
METHOD, //方法声明上
PACKAGE, //包声明上
PARAMETER, //参数声明上
TYPE //类,接口和枚举类的声明上
}
对于PACKAGE的使用,必须是在package-info.java文件中使用
3. @Documented
使用@Documented所标记的annotation,在生成javadoc文档
时会将annotation信息也加入。
eg:
@Documented
public @interface myAnnotation{
}
4. @Inherited
表示一个annotation是否会被使用该annotation的类的子类所继承