包装类与泛型
- 1 包装类
- 1.1 基本类型包装类
- 1.2 Integer类
- 1.3 自动装箱 / 拆箱
- 2 泛型
- 2.1 泛型概述
- 2.2 泛型的用法
- 2.3 类型通配符
1 包装类
1.1 基本类型包装类
基本类型包装类的作用
- 将基本数据类型封装成对象 的好处在于可以在对象中定义更多的功能方法操作该数据
public static void main(String[] args) {
//需求:我要判断一个整数是否在 int 范围内?
//Integer
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
常用的操作之一:用于基本数据类型与字符串之间的转换
基本数据类型对应的包装类:
1.2 Integer类
包装一个对象中的原始类型 int 的值
- 构造方法
public static void main(String[] args) {
/* 已经过时
Integer i1 = new Integer(100);
Integer i2 = new Integer("100");
System.out.println(i1);
System.out.println(i2);*/
Integer i3 = Integer.valueOf(200);
Integer i4 = Integer.valueOf("200");
System.out.println(i3);
System.out.println(i4);
}
- 成员方法
static int parseInt(String s)
:将字符串类型的整数变成 int 类型的整数
public static void main(String[] args) {
String s1 = "100";
int i1 = 200;
System.out.println(s1 + i1);//100200 --- 字符串+任意的数据类型 结果都是一个字符串
//String ---> int
int i2 = Integer.parseInt(s1);//可以将字符串类型的整数变成int类型的整数
System.out.println(i2 + i1); // 300
//int ---> String
//方式一: +""
int i3 = 100;
String s2 = i3 + "";
System.out.println(s2 + 100); // 100100
//方式二: 可以调用String类中valueof方法
String s3 = String.valueOf(i3);
System.out.println(s3 + 100); //100100
}
1.3 自动装箱 / 拆箱
自动装箱:把基本数据类型转换为对应的包装类类型
自动拆箱:把包装类类型转换为对应的基本数据类型
public static void main(String[] args) {
// 更为简单地获取Integer的方式
Integer i1 = 100;
// 对象 = 默认是一个基本数据类型
//jdk1.5的特性 --- 自动装箱
//装箱: 把一个基本数据类型 变量对应的包装类.
//自动: Java底层会帮我们自动的调用valueof方法.
System.out.println(i1);
//jdk1.5的特性 --- 自动拆箱
//拆箱: 把一个包装类型 变成对应的基本数据类型
int i2 = i1;
System.out.println(i2);
Integer i3 = 100; //自动装箱机制
i3 += 200;//i3 = i3 + 200;
//会把i3这个对象变成基本数据类型100.
//100 + 200 = 300
//把基本数据类型300再次自动装箱变成Integer对象赋值给i3
System.out.println(i3);
//细节:null可赋值给引用类型,但是不可以赋给基本类型
Integer i4 = null;
if(i4 != null){
i4 += 200;
System.out.println(i4);
}
注意:
- 在使用包装类类型的时候,如果做操作,最好先判断是否为null,推荐的是,只要是对象在使用前就必须进行不为null的判断
练习:字符串中数据的处理
//需求:有一个字符串:“91 27 46 38 50”,把其中的每一个数存到int类型的数组中
//步骤:
//定义一个字符串
//把字符串中的数字数据存储到一个int类型的数组中
//遍历数组输出结果
public static void main(String[] args) {
String s = "91 27 46 38 50";
//获取字符串中的每一个数字.
String[] strArr = s.split(" ");
//创建一个int类型的数组.
int [] numberArr = new int[strArr.length];
//把strArr中的数据进行类型转换并存入到int数组中
for (int i = 0; i < strArr.length; i++) {
int number = Integer.parseInt(strArr[i]);
numberArr[i] = number;
}
//遍历int类型的数组
for (int i = 0; i < numberArr.length; i++) {
System.out.println(numberArr[i]);
}
}
2 泛型
2.1 泛型概述
不写泛型的弊端
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add(123);
Iterator it = list.iterator();
while(it.hasNext()){
String next = (String) it.next(); // 强制类型转换
int len = next.length();
System.out.println(len);
}
}
泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制
- 泛型的好处
- 把运行时期的问题提前到了编译期间
- 避免了强制类型转换
- 泛型的定义格式
<类型>
:指定一种类型的格式,尖括号里面可以任意书写,一般只写一个字母。例如:<E>、 <T>(不知道什么类型)<类型1,类型2…>
:指定多种类型的格式,多种类型之间用逗号隔开。例如: <E,T> 、<K,V>
2.2 泛型的用法
泛型可以使用的地方:
- 类后面 —— 泛型类
- 方法申明上 —— 泛型方法
- 接口后面 —— 泛型接口
我们也可以自定义泛型
1. 泛型类
如果一个类的后面有 <E> ,表示这个类是一个泛型类。
创建泛型类对象时,必须要给这个泛型确定具体的数据类型。
泛型类格式:
修饰符 class 类名<类型> { }
范例:
public class Test<T>{}
此处的 T 可以随便写为任意标识,常见的如T、E、K、V等形式的参数用于表示泛型
示例代码:
泛型类
public class Box<E> {
private E element;
public E getElement() {
return element;
}
public void setElement(E element) {
this.element = element;
}
}
测试类
public static void main(String[] args) {
Box<String> box1 = new Box<>();
box1.setElement("给小丽的土味情话");
String element1 = box1.getElement();
System.out.println(element1);
Box<Integer> box2 = new Box<>();
box2.setElement(19);
Integer element2 = box2.getElement();
System.out.println(element2);
}
2. 泛型方法
泛型方法格式:
修饰符 <类型> 返回值类型 方法名(类型 变量名) { }
范例:
public <T> void show(T t){}
示例代码:
// 定义一个泛型方法,传递一个集合和四个元素,将元素添加到集合中并返回
public static void main(String[] args) {
ArrayList<String> list1 = addElement(new ArrayList<String>(), "a", "b", "c", "d");
System.out.println(list1); // [a, b, c, d]
ArrayList<Integer> list2 = addElement(new ArrayList<Integer>(), 1, 2, 3, 4);
System.out.println(list2); // [1, 2, 3, 4]
}
public static <T> ArrayList<T> addElement(ArrayList<T> list , T t1 ,T t2 ,T t3 ,T t4){
list.add(t1);
list.add(t2);
list.add(t3);
list.add(t4);
return list;
}
3. 泛型接口
泛型接口格式:
修饰符 interface 接口名<类型> { }
范例:
public interface Generic<T>{}
泛型接口的使用方式:
- 实现类也不给具体的泛型
- 实现类确定具体的数据类型
示例代码:
public class GenericityInterface {
public static void main(String[] args) {
GenericityImpl1<String> genericity = new GenericityImpl1<>();
genericity.method("小丽给我的土味情话");
GenericityImpl2 genericityImpl2 = new GenericityImpl2();
genericityImpl2.method(19);
}
}
interface Genericity<E>{
public abstract void method(E e);
}
// 实现类确定具体的数据类型
class GenericityImpl2 implements Genericity<Integer>{
@Override
public void method(Integer integer) {
System.out.println(integer);
}
}
// 实现类也不给具体的泛型
class GenericityImpl1<E> implements Genericity<E>{
@Override
public void method(E e) {
System.out.println(e);
}
}
2.3 类型通配符
类型通配符:<?>
ArrayList<?>
:表示元素类型未知的 ArrayList,它的元素可以匹配任何的类型- 但是并不能把元素添加到 ArrayList中了,获取出来的也是父类类型
类型通配符上限:<? extends 类型>
ArrayListList <? extends Number>
:它表示的类型是Number或者其子类型
类型通配符下限:<? super 类型>
ArrayListList <? super Number>
: 它表示的类型是Number或者其父类型
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
ArrayList<Number> list3 = new ArrayList<>();
ArrayList<Object> list4 = new ArrayList<>();
method(list1);
method(list2);
method(list3);
method(list4);
getElement1(list1);
getElement1(list2);//报错
getElement1(list3);
getElement1(list4);//报错
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
}
// 泛型通配符: 此时的泛型?,可以是任意类型
public static void method(ArrayList<?> list) {
}
// 泛型的上限: 此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(ArrayList<? extends Number> list) {
}
// 泛型的下限: 此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(ArrayList<? super Number> list) {
}