JDK5部分新特性----1
静态导入 可变参数数组 享元设计模式思想
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
1. 静态导入
1). 静态导入基本概念
静态导入的应用背景以及使用
[1]. 采用import关键字导入的是某个包下面的某个类
e.g. import java.lang.Math.*;
System.out.println(Math.max(6, 3));
要使用Math下的静态方法max(),必须使用“类名.静态成员方法名”的格式
[2]. 为了简化书写,JDK5引入了静态导入。import static两个关键字一起使用,然后在文件中直接采用静态方法名来访问某个类下的静态成员从而省去“类名.”这个前缀
e,g,
import static java.lang.Math.*;
public class StaticImport {
public static void main(String[] args) {
System.out.println(Math.max(6, 3));//类名.静态成员方法名
System.out.println(abs(3 -6));//采用静态导入,直接采用静态方法名进行访问
}
}
2. 可变参数数组
1).可变参数数组之前出现的问题
代码书写出现的问题
当一个方法接收参数不固定的时候,可变参数数组之前的解决方式有两种
[1]. 直接使用方法重载:有几种不同的参数接受方法,就写出来几个方法,保证方法名相同而参数列表不同即可形成重载
e.g. 分别求出两个数和三个数的和
public class Test {
public static void main(String[] args) {
System.out.println(add(2,3));
System.out.println(add(2,3,5));
}
public static int add(int num1, int num2){
return num1 +num2;
}
public static int add(int num1, int num2, int num3){
return num1 +num2+ num3;
}
}
【缺点】十分死板!!如果参数的组成个数很多种,那么势必会写出来很多内容重复的重载的函数。
[2]. 将参数不固定的所有的数先包装成数组,再将数组传入指定的方法:
e.g.
public class Test {
public static void main(String[] args) {
//现将2,3存入数组,再将数组传入要调用的方法
int[] arr =new int[]{2,3};
System.out.println(add(arr));
//现将2,3,5存入数组,再将数组传入要调用的方法
arr=new int[]{2,3,5};
System.out.println(add(arr));
}
//仅仅需要一个方法。
private static int add(int[] arr) {
int sum =0;
for(int i=0; i<arr.length; i++)
sum+=arr[i];
return sum;
}
}
【和方法重载相比的优势】所有因参数个数不同而重载的方法全部统一成一个以数组作为参数的方法
【和方法重载相比的劣势】但是,在调用这个以数组作为参数的方法之前,一定要把所有参数打包成一个数组,才能使用。这是这种改进方法的麻烦之处
[3]. JDK5在修改[2]这种方式的基础之上,引进了可变参数数组的技术,融合重载好处(参数直接写到实参)+ 打包成数组的好处(统一重载方法的数目)。
2). 可变参数数组的特点以及使用
(1). 可变参数数组的表现形式
数据类型… 参数名
e,g, private static int add(int ... args)
(2). 使用可变参数的实质
调用含有可变参数的方法时候,javac为可变参数部分隐含新建一个数组,所以使用可变参数的实质是把需要的参数打包成一个数组再调用以数组作为参数的方法。
(3). 可变参数数组的特点
[1]. 只能出现在参数列表的最后
[2]. ... 位于参数类型和参数名之间,前后有无空格都可以
[3]. 依据可变参数使用的实质,可以在可变参数所在的方法中以数组的使用形式来操作这个可变参数***
【注意】可变参数的定义式:数据类型…参数名 其中…之前的数据类型一定是被打包成数组的每个元素的类型,而…后面的参数名实际上打包成数组的集合名字!!!是一种总分的关系!!!!千万别弄错了!!!
改进代码:
public class Test {
public static void main(String[] args) {
//现将2,3存入数组,再将数组传入要调用的方法
System.out.println(add(2,3));
//现将2,3,5存入数组,再将数组传入要调用的方法
System.out.println(add(2,3,5));
}
//采用可变参数的形式来改进代码
private static int add(int ... args) {
int sum =0;
for(int i=0; i< args.length; i++)//以数组的形式来操作可变参数
sum+=args[i];
return sum;
}
}
(4). 可变参数数组拓展性 ----单个元素【很特殊】
[1]. 当函数的参数是普通数组类型时候
此时传入函数的实参仅仅是一个基本数据类型,则编译失败。
【举例】
public static void printArray(int[] args){
for(int e: args){
System.out.print(e+" ");
}
}
传入的实际参数是一个1,会编译报错:
【改正办法】
无论数组中有几个元素,都手动把元素打包成数组
printArray(new int[]{1}); //编译通过
[2]. 当函数的参数是可变参数数组类型时候
{1}.【实质+核心!!!!】
普通类型数组和可变参数类型数组做函数的参数的时候,实际上是一样的。
***但是, 可变参数数组是javac自动把多个分散独立元素自动打包成普通类型的数组。***
{2}. 可变参数数组仅仅是一种书写形式上的简化
{3}. 正是由于javac可以把多个分散独立元素自动打包成数组,所以此时当传入函数的实参仅仅是一个基本数据类型的时候,编译通过。
【举例】
public static void printArrayII(int...args){
for(int e: args){
System.out.print(e+" ");
}
}
传入的实际参数是一个1,会编译成功!!!:
【模拟过程】
3. 享元设计模式思想
(1). JDK5出现的现象
Integer i1 =137;//自动装箱成整形对象
Integer i2 =137;//自动装箱成整形对象
System.out.println( i1==i2);//打印出false
i1 =13;
i2 =13;
System.out.println( i1==i2); //打印出true
【**小知识点**】:当一个整数大小在一个字节B(-128~ +127)的取值之间的时候,当被自动包装为相应的对象之后,JVM就会将这些对应的基本数据类型值很小的基本数据类型对应的对象存入缓存池中,以便程序的其他部分复用这个对象。因为Java认为值很小的对象使用频率很高。
【常常使用的东西,存放到公共空间,大家分享,节省内存】
------享元设计模式思想的体现
【分析上面的代码】
Integer i1 =137;//此时相当于 Integer i1 =new Integer(137);
Integer i2 =137;//此时相当于 Integer i2 =new Integer(137);
/*
由于i1和i2指向了两个new出来的堆内存的对象,所以两者的内存地址一定不同,所以 ==判断为false
*/
System.out.println( i1==i2);//打印出false
i1 =13; //13在[-128, +127]之间,并且
//第一次出现,所以相当于i1 =new Integer(13);
//此时JVM就会将这堆内存的对象存放到缓存池中
i2 =13; //这个时候,13再一次出现,JVM此时去缓存池中找有没有值为13的整形
//对象。发现有,就把这个i2指向这个堆内存的对象。
/*
这时候,i2和i1指向了同一个地址的对象,所以 ==判断结果为true
*/
System.out.println( i1==i2); //打印出true
【例子2】
Integer i3 =Integer.valueOf(137);
Integer i4 =Integer.valueOf(137);
System.out.println(i3 ==i4);//打印false
i3 =Integer.valueOf(13);
i4 =Integer.valueOf(13);
System.out.println(i3 ==i4); //打印true
思想同上!!仍是享元设计模式的体现!!!
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------