java1.5特性_Java1.5新特性(一)

自动拆装箱

8种基本类型与其对应包装器类型可以直接互换,8种基本类型与其对应包装类分别为

基本类型 包装类

short Short

int Integer

long Long

float Float

double Double

byte Byte

char Character

boolean Boolean

自动拆装箱概述

在JDK1.5之后,Java允许把基本类型与其对应的包装器类型之间自动相互转换。

自动装箱:Integer i =100; 把int类型之间赋值给Integer类型;

自动拆箱:int i =new Integer(100); 把Integer类型直接赋值给int类型

自动拆装箱原理

自动拆装箱是由编译器完成的,编译器编译代码时把 Integer i = 100; 加工为Integer i = Integer.valueOf(100); 把int a = i; 加工为 int a = i.intValue();

自动拆装箱演变题目

Integer i1 = 100;

Integer i2 = 100;

boolean b1 = i1 == i2;//结果为true

Integer i3 = 200;

Integer i4 = 200;

boolean b2 = i3 == i4;//结果为false

为什么会出现这种情况呢?上面我们说到,Integer i1 = 100;这是java1.5新特性自动装箱,实际上是编译器加工为 Integer i1 = Integer.valueOf(100);那么现在的问题就是,为什么i1,i2是同一个对象,而i3,i4不是同一个对象?

问题出在Integer.valueOf()方法,Integer类的内部缓存了从-128到127的256个Integer对象,如果valueOf()方法需要把这个范围之内的整数转换成Integer对象时,valueOf不会去new对象,而是从缓存中直接获取,这就会导致valueOf(100)方法执行两次,都是从缓冲中获取同一个Integer对象。如果valueOf()方法收到的参数不在缓存范围之内,那么valueOf()方法会new一个新对象,所以执行两次valueof(200),就会new两个对象,两个对象当然不同,所以i3 != i4,b2为false,而b1为true。

自动拆装箱演变题目2

Integer i1 = 59;

int i2 = 59;

Integer i3 = Integer.valueOf(59);

Integer i4 = new Integer(59);

System.out.println(i1 == i2);//true

System.out.println(i1 == i3);//true(自动拆箱)

System.out.println(i3 == i4);//false

System.out.println(i2 == i4);//true(自动拆箱)

分析:

Integer i1 = 59; 如同上面分析,调用Integer的valueOf方法,返回一个Integer对象i1。

int i2 = 59; i2是一个基本类型,存储在栈中。

Interger i3 = Integer.valueOf(59); 如同上面分析,可以知道返回缓存中已经存在的Integer对象,i1 == i3

Integer i4 =new Integer(59); 直接创建一个新的Integer对象。由此可知,i4对象和i1,i3不相等,因为不是同一个对象。

System.out.println(i1 == i2); 当包装器类型和基本数据类型进行“==”比较时,包装器类型会自动拆箱为基本数据类型。i1是Integer对象,而i2是基本类型int,所以这里比较的不是地址,而是值。Integer会自动拆箱为int,然后进行比较,所以i1和i2相同。

System.out.println(i1 == i3); 与上面分析的结果相同,结果为true

System.out.println(i3 == i4); 与上面分析的结果相同,结果为true

System.out.println(i2 == i4);当包装器类型和基本数据类型进行“==”比较时,包装器类型会自动拆箱为基本数据类型。i4是Integer对象,而i2是基本类型int,所以这里比较的不是地址,而是值。Integer会自动拆箱为int,然后进行比较,所以i4和i2相同。

注意:八种类型除了double和float类型的包装类valueOf方法没有缓存对象,其他6种都有缓存对象。

可变参数

可变参数就是一个方法可以接收多个参数,例如:func(1,2,3,...)

定义可变参数方法

pubic void func(int... arr){} 上面方法func()的参数类型为int..., 其中“...”不是省略号,而是定义参数类型的方式。参数arr就是可变参数类型,可以理解为public void fun(int[] arr), 所以可以理解为int... 是一种新的定义数组形参的方式,代替int[],但是注意只有在方法的形参中可以使用"...",可变参数其实就是数组类型,只不过在调用方法的时候更方便一些,由编译器帮我们把多个实参放到一个数组中传递给形参。

可变形参方法的限制

一个方法最多只能有一个可变参数。

可变参数必须是方法的最后一个参数。

增强for循环

增强for循环是for的一种新用法,用来循环遍历数组和集合。

增强for的语法

for(元素类型 e: 数组或者集合对象){}例如:

int[] array={1,2,3};

for(int i : array){

System.out.println("i = " + i);

}

增强for循环的冒号左边是定义变量,右边必须是数组或者集合类型。for循环内部会依次把array数组中的元素赋值给变量i。

增加for的优缺点

只能从头到尾的遍历数组或集合,而不能只遍历部分;

在遍历List或数组时,不能获取当前元素下标;

增强for使用便简单,这是它唯一的优点了;

增强for比使用迭代器方便

增强for原理

任何实现了Iterable接口的类,都有返回Iterator的方法,增强for的底层就是迭代器,任何实现了Iterable接口的类,都可以使用增强for来遍历,但是注意Map并没有实现Iterable接口,所以不能直接使用增强for遍历。下面是一个实现Iterable接口使用增强for循环遍历的例子:

import org.junit.Test;

import java.util.Iterator;

public class Demo3 {

@Test

public void func(){

Word word = new Word("abcd edf hijk lmn");

for(String s: word){

System.out.println(s);

}

}

}

class Word implements Iterable{

private String text;

public Word(String s){

this.text=s;

}

@Override

/*

* 希望每次遍历一个单词

*/

public Iterator iterator() {

return new Iterator() {

private String[] wordArray = text.split("\\s+");

private int index =0;//表示从0下标开始遍历

@Override

public boolean hasNext() {

return index < wordArray.length;

}

@Override

public String next() {

return wordArray[index++];

}

};

}

}

泛型

泛型概述

泛型是JDK5.0的新特性,主要应用在集合类上。有了泛型之后,集合类与数组就越来越像了。例如:Object[] objs = new Object[10], 可以用来存储任何类型的对象。 String{} strs = new String[10]就只能用来存储String类型的对象。

同样的,ArrayList list =new ArrayList()可以用来存储任何类型的对象。ArrayList list = new ArrayList()就只能用来存储String类型的对象。

理解泛型类

具有一个或多个类型变量的类称之为泛型类

泛型类具有一个到多个泛型变量,在创建泛型类对象时,需要为泛型变量知道值。泛型变量只能赋值为引用类型,而不能是基本类型。例如ArrayList类中有一个泛型变量E,在创建ArrayList类的对象时需要为E这个泛型变量指定值。下面是一个泛型类的创建和使用。

import org.junit.Test;

/**

* 创建泛型类

*/

public class Demo4 {

@Test

public void func(){

A a1 =new A();//创建对象时给类型变量赋值

A a2 = new A();//每个对象可以给出不同的值

}

}

/*

* 类名称后给出尖括号,尖括号内给出类型变量

* 如果是多个类型变量,使用逗号分隔

* 命名要求:单个大学字母

* 参数化类型:A

* 类型变量:T,它是一个变量,需要赋类型值。

*/

class A {

/*

* 在类内,可以使用类型变量,在以下位置可以使用:

* * 实例成员类型上

* * 实例方法参数和返回值上

* * 构造器的参数类型上

*

* * static的成员和方法上不能使用类型变量T

*/

private T t;

public A(T t){

this.t = t;

}

public A(){

}

public T getT(){

return this.t;

}

public void setT(T t){

this.t = t;

}

}

使用泛型对象

创建泛型对象时,引用和new两端的泛型类型需要一致,比如:List list = new ArrayList();两端都需要是String类型,如果不一致就会出错。eg: List list = new ArrayList();//编译失败!

泛型的好处

将运行期遇到的问题转移到了编译期

泛型不可能去除所有类型转换,但可以减少类型转换操作

在循环遍历集合类时,方便了很多

一定程度上提高了安全性

泛型方法定义

不只可以创建泛型类,还可以创建泛型方法。泛型方法不受类的限制,即为,方法所在类即使不是泛型类,也可以有泛型方法。定义泛型方法的格式:修饰符 返回值 方法名

一般泛型方法的特点:

返回值会使用泛型

在参数中会使用泛型 下面是一个使用泛型方法的例子:

package oneday.one;

import org.junit.Test;

/**

* Created by ZPF on 2019/10/29.

*/

public class Demo5 {

@Test

public void func1(){

// String name = AA.get(new String[] {"zhangsan", "lisi", "abc", "def"});

String name = AA.get(new String[] {"zhangsan", "lisi", "abc", "def"});

System.out.println(name);

}

}

class AA{

/*

* 泛型方法不受类的限制,即为,方法所在类即使不是泛型类,也可以有泛型方法

*/

/*

* 定义泛型方法的格式:

* 修饰符 返回值 方法名

* 一般泛型方法的特点:

* * 返回值会使用泛型

* * 在参数中会使用泛型

*/

//显示数组中间值

public static T get(T[] array){

return array[array.length/2];

}

}

ArrayList类中的toArray方法也是泛型方法:

/*如果传入数组的长度小于size,返回一个新的数组,大小为size,类型与传入数组相同。

所传入数组长度与size相等,则将elementData复制到传入数组中并返回传入的数组。

若传入数组长度大于size,除了复制elementData外,还将把返回数组的第size个元素置为空。

其中:elementData存储ArrayList内的元素,size表示它包含的元素的数量,都是ArrayList的属性。*/

public T[] toArray(T[] a) {

if (a.length < size)

// Make a new array of a‘’s runtime type, but my contents:

return (T[]) Arrays.copyOf(elementData, size, a.getClass());

System.arraycopy(elementData, 0, a, 0, size);

if (a.length > size)

a[size] = null;

return a;

}

泛型擦除

泛型是编译器状态,所有的泛型会被编译器擦除,变成了Object类型!

编译器会在适当的位置上添加强制转化。

继承(或实现)泛型类(或接口)

import org.junit.Test;

public class Demo6 {

@Test

public void func2(){

BB bb =new BB();

bb.setBean("hello");//参数必须是“String”类型

BBB bbb = new BBB<>();

bbb.getBean();//返回值是Integer类型

}

}

class B {

private T bean;

public T getBean(){

return bean;

}

public void setBean(T t){

this.bean = t;

}

}

/*

* BB类不是泛型类,但是它的父类是泛型类

* 如果父类是泛型类,那么子类在继承时需要给父类传递类型变量值!(比如:下面的BB类传递了String)

* 例如BB类,它所继承的是B,也就是说,在父类出现的所有T等同与String

*/

class BB extends B{

}

/*

* BBB类也是一个泛型类,它继承了父类泛型类

* 给父类传递的是自己的泛型

*

*/

class BBB extends B {

}

class MyComparable implements Comparable{

@Override

public int compareTo(String o) {

return 0;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值