------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
JDK1.5新特性
1 静态导入
2 自动装箱拆箱
3 增强for
4 函数可变参数
5 枚举
----------------
1 静态导入
jdk 1.5支持将类中的静态方法导入。
import static java.lang.Math.max;
import static java.lang.Math.abs;
System.out.println(max(123, 231))
System.out.println(abs(3-6));
-------------------------
2 可变参数
当一个函数所接收的参数个数不定时可使用可变参数
需注意几点:
1 表示方式:类型...
2 只能放在参数列表的最后;
3 在函数体中以数组的形式调用;
changeableParm("可变参数测试",1,2,3);
public static void changeableParm(String name,int... a)
{
int count =0;
for(int i=0;i<a.length;i++)
{
count+=a[i];
}
System.out.println(name+":"+count);
}
在方法调用时编译器会为参数隐式的创建一个数组传给函数
------------------------------------
3 增强for循环
语法:
for(type 变量名:集合变量名)
{
}
特点:可对集合中的元素进行遍历。
但存在一定的局限性:如不能像传统for那样对for中的循环条件进行灵活的操作
如 for(int a=0;a<XXX.lenght;a +=2)//可每跳跃式的遍历
注意能使用增强for循环的集合必须是实现了Itratorable接口的集合
-------------------------------------------
4 基本数据类型的自动装箱和拆箱
Integer i2 = 2;/*存在装箱操作:i2为引用数据类型,2为基本数据类型;
将基本数据了类型赋值给引用数据类型是不行的,此处隐藏了
new Integer(2);
*/
System.out.println(i2 + 3);//进行了拆箱操作把引用性的i2拆箱转化成了整形为基本数据类型3相加
----------------------------
5枚举
枚举 enum
1枚举的作用
限制某个对象的取值范围,让编译器能在编译时期对非法赋值进行检测。提高代码的安全性。 比如对一周的赋值 程序员定义可能为1-7;当出现0赋值时程序在编译时期时不能检测的。采用枚举之后能很好的在编译期检测非法赋值。
2 用普通类模拟实现枚举
用java的普通类实现枚举
思路分析: 如何限制一个引用的赋值范围?
:该类对象的值由该类对象自己定义。在外部不能new
:私有化构造函数
如何给外界使用这些值呢?
static 修饰这些定义在类内部的值
如何让外界知道可赋值时那些呢?
:得对外提供访问方法。
public abstract class weekday {
//如何向外界提供该类引用值呢? static
public static weekday sun = new weekday(){
// 匿名内部类
@Override
public weekday next() {
// TODO Auto-generated method stub
return mon;
}
};
public static weekday mon = new weekday(){
@Override
public weekday next() {
// TODO Auto-generated method stub
return sun;
}};
private weekday()//外界不能随便创建该对象赋值给该类对象
{
}
// //如何让外界知道可取那些值呢?:得提供方法
// public weekday next()
// {
// if(this == sun)//存在一定的缺陷性:当存在多个值时会写多个if....else if()....判断
// return mon;// 如何改进呢?:将大量的if ...else..语句转换成一个个独立的类,
// //每个类完成一个if(绝了这思路)
// else
// return sun;
// }
public abstract weekday next();
//如何让外界知道获取的值是啥呢? :复写toString方法
public String toString()
{
return this==sun?"sunday":"moenday";
}
}
在mian函数中的调用
weekday day = weekday.sun;
System.out.println(day);
System.out.println(day.next());
参见如何实现:将大量的if ...else..语句转换成一个个独立的类,每个类完成一个if;
3 枚举的一些常见方法
public enum weekday1 {
sun("name"),mon,Tus,wen,thi,fri,sta;//可加 ; 也可不加;此处相当于在为Weekday1 类型的对象取名
private weekday1(){
System.out.println("无惨构造函数被调用");
};//可为枚举指定构造函数
private weekday1(String i){
System.out.println(i);
};
}
weekday1 weekday = weekday1.sun;
System.out.println(weekday);//枚举自动复写了toString方法
System.out.println(weekday.name());
System.out.println(weekday.ordinal());//获取位置该对象在对象数组中的值
System.out.println(weekday1.valueOf("sun").toString());//静态方法:1 通过对象的字符名获得对象
System.out.println(weekday1.values().length);//静态方法:2 获取所有值对象数组 在需要遍历时使用
注意:1 通过字符串获取枚举对象的方法 valueOf("name");enm关键字相当于一个特殊的class ;2 枚举相当于一个特殊的类编译后产生的仍是.class文件
4 带构造参数的枚举
public enum weekday1 {
sun("name"),mon,Tus,wen,thi,fri,sta;//此处相当于在为Weekday1 类型的对象取名
private weekday1(){
System.out.println("无惨构造函数被调用");
};//可为枚举指定构造函数
private weekday1(String i){
System.out.println(i);
};
}
注意:当定义一个枚举
public enmu weekday1
{ sun,mon,tus,wen,thi,fri,sta};时会隐式的调用无惨构造函数;等价于{ sun(),mon(),tus(),wen(),thi(),fri(),sta()};
当我们为枚举类定义了自己的构造函数时可通过上述代码 sun( 参数) 的方式调用该构造函数
5 带抽象函数的枚举
// 带抽象方法的枚举
public enum TrafcLamp
{
GREEN(200){
public TrafcLamp next()
{
return null;
}
},YELLOW(300){
public TrafcLamp next()
{
return null;
}
},RED(100){
public TrafcLamp next()
{
return null;
}
};
public abstract TrafcLamp next();
private int time;
private TrafcLamp (int time)
{
this.time = time;
}
}
带抽象函数枚举图解
-------------------------------------------------------------
枚举和单例
枚举很单例在实现原理上时一直的都是private 构造函数
字节对外提供该类对象的引用对象给外界使用。
枚举只有一个成员时,就可以作为一种单例的实现方式。
枚举和单例的区别与联系
1 单例中类对象应用为private修饰的,提供静态方法来对外界暴露该引用
2 单例可以有 “饿汗”和 “懒汉”2种实现方式;而枚举采用的是“饿汗模式”。
-----------------------------------------------------------------------
享元模式
享元模式
:享元模式是对象的结构模式。享元模式以共享的方式高效地支持大量的细粒度对象。
:享元模式的结构
享元模式采用一个共享来避免大量拥有相同内容对象的开销。这种开销最常见、最直观的就是内存的损耗。享元对象能做到共享的关键是区分内部状态(Internal State)和外部状态(External State)。
一个内部状态是存储在享元对象内部的,并且是不会随环境的改变而有所不同。因此,一个享元可以具有内部状态并可以共享。
一个外部状态是随环境的改变而改变的、不可以共享的。享元对象的外部状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。外部状态不可以影响享元对象的内部状态,它们是相互独立的。
我的理解:就是将对象的不会因为对象不同而改变的数据如(静态类成员,字符串常量)给贡献出来进行不同对象的共享:时内存中该数据始终值存在一个复本,不会因对象的增加而增加。以减小内存的开销。
需注意的是:作为享元的数据 必须是对象无关性的。必须是始终不变的。如java中的String 为final型数据,在内存中为其建立常量池保存字符串常量(唯一性)。当程序中有使用到字符串常量时,java先到池中查找是否存在,如存在就直接使用,如不存在才将新的字符串加载进内存。
作为享元的数据不能太大:享元数据的生命周期相对较长,会常驻内存。这就是FliyWiet(超轻量级)名字的由来。
享元模式应用:
Integer i3 = 34;
Integer i4 = 34;
System.out.println(i3 == i4);// true
Integer i3 = 134;
Integer i4 = 134;
-127 --- 128
System.out.println(i3 == i4);// false
在JAVA语言中,String类型就是使用了享元模式。String对象是final类型,对象一旦创建就不可改变。在JAVA中字符串常量都是存在常量池中的,JAVA会确保一个字符串常量在常量池中只有一个拷贝。String a="abc",其中"abc"就是一个字符串常量。
String a = "abc";
String b = "abc";
System.out.println(a==b);
结果为true
这就说明a和b两个引用都指向了常量池中的同一个字符串常量"abc"。这样的设计避免了在创建N多相同对象时所产生的不必要的大量的资源消耗。