泛型
- 概述:是一种把类型明确工作推迟到调用方法或创建对象时才确定的特殊类型
- 格式:<引用类型,引用类型…>
- 好处:
(1)避免了向下转型
(2)泛型只在编译期有效,在运行期就擦除了,所以把运行期的问题提前到了编译期
举个例子:
package org.org.westos.demo;
import java.util.ArrayList;
public class MyClass {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(100);
list.add(200);
list.add(300);
//获取第一个元素
Object o = list.get(0);
//要使用这个元素,需向下转型
Integer integer = (Integer) o;
//使用泛型创建集合
//一旦在创建对象确定了类型,那么集合中的所有元素都是这一个类型
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(400);
arrayList.add(500);
arrayList.add(600);
//不需要向下转型,因为集合元素就是Integer类型
Integer integer1 = arrayList.get(0);
System.out.println(integer1);
}
}
- 应用(把学生对象作为泛型)
package org.org.westos.demo;
import java.util.ArrayList;
public class MyClass {
public static void main(String[] args) {
//泛型是学生对象
ArrayList<Student> list = new ArrayList<>();
//集合中的每一个元素都是一个学生对象
list.add(new Student("张三",19));
list.add(new Student("李四",22));
list.add(new Student("王五",25));
//如果要获取集合中的元素,只需遍历集合
//这里使用新式for循环遍历
for (Student student : list) {
//获取单个元素中的姓名
String name = student.getName();
//获取单个元素中的年龄
int age = student.getAge();
System.out.println(name+"--"+age);
}
}
}
- 泛型可以运用在类,接口和方法上
(1)泛型类
//这是一个普通类,返回值类型已确定
public class Putong {
private Object obj;
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
//这是一个泛型类,返回值用泛型T代替
public class Fanxing<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
package org.org.westos.demo;
public class MyClass {
public static void main(String[] args) {
//创建普通类对象,数据类型已经固定,使用需向下转型
Putong putong = new Putong();
putong.setObj(100);
Object obj = putong.getObj();
Integer integer = (Integer) obj;
//使用泛型类来创建对象,可以在创建时在确定数据类型,避免转型
Fanxing<Integer> list = new Fanxing<>();
list.setObj(100);
Integer integer1 = list.getObj();
}
}
(2)泛型接口
//定义泛型接口,返回值,参数都不明确
interface MyInterface<T,U>{
U show(T t);
}
package org.org.westos.demo;
public class MyClass {
public static void main(String[] args) {
//使用匿名内部类时就必须明确接口上的泛型,是什么具体类型
new MyInterface<String, String>() {
@Override
public String show(String s) {
return null;
}
};
}
}
(3)泛型方法
package org.org.westos.demo;
public class MyClass {
public static void main(String[] args) {
AA aa = new AA();
aa.set(100);
aa.set("abc");
}
}
class AA{
//定义普通方法
public void set(String str){
System.out.println(str);
}
public void set(Integer num){
System.out.println(num);
}
//定义泛型方法,好处就是不用把每一个类型的方法都写一遍,用泛型可以简化代码
public <T> void set(T t){
System.out.println(t);
}
}
- 通配符
List<?> :通配符?可以代替多个真正字符,用于不确定真正字符时
向上限定:List<? super T>,指在创建对象时泛型只能是T或者T的父类,包括Object
向下限定:List<? extends T>,指在创建对象时泛型只能是T或者T的子类
package org.org.westos.demo;
import java.util.ArrayList;
public class MyClass {
public static void main(String[] args) {
//? 泛型通配符
//创建一个cat类对象
ArrayList<?> cats = new ArrayList<Cat>();
//向上限定,只能是动物和它父类
ArrayList<? super Animal> objects = new ArrayList<Animal>();
ArrayList<? super Animal> objects1 = new ArrayList<Object>();
//向下限定,只能是动物和它子类
ArrayList<? extends Animal> object2 = new ArrayList<Animal>();
ArrayList<? extends Animal> object3 = new ArrayList<Dog>();
ArrayList<? extends Animal> object4 = new ArrayList<Cat>();
}
}
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}
增强for
- 概述:简化数组和集合的遍历
- 格式:
for(元素数据类型 变量名 : 数组或集合){
变量就是元素,直接操作即可
} - 遍历
(1)数组的遍历
(2)集合的遍历
package org.org.westos.demo;
import java.util.ArrayList;
public class MyClass {
public static void main(String[] args) {
int[] arr = {10,20,30,40};
//用新式for循环遍历数组,确定元素类型
for (int i : arr) {
//变量名i就是数组元素,直接输出即可
System.out.println(i);
}
System.out.println("------");
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(100);
arrayList.add(200);
arrayList.add(300);
//用新式for循环遍历集合,确定元素类型
for (Integer integer : arrayList) {
//变量名i就是集合元素,直接输出即可
System.out.println(integer);
}
}
}
注意,在用新式for循环遍历的时候,不能对集合元素进行增删操作
可变参数
-
概述:编写方法时不知定义几个参数,使用可变参数可以一次接收多个参数
-
格式:修饰符 返回值类型 方法名(数据类型… 变量名)
-
注意事项:
(1)变量名实质上是一个数组
(2)如果还有其他参数,应写在可变参数之前,因为写在后面将收不到传入的参数,会被可变参数全部吸收 -
应用(实现N个数相加)
package org.org.westos.demo;
public class MyClass {
public static void main(String[] args) {
//实现3个数的相加
int sum1 = getSum(10,20,30);
System.out.println(sum1);
//实现5个数的相加
int sum2 = getSum(10,20,30,40,50);
System.out.println(sum2);
}
//编写方法,参数为可变参数,可实现N个数相加
public static int getSum(int... num){
int sum=0;
//遍历可变参数,然后相加求和
for (int i : num) {
sum+=i;
}
return sum;
}
}
验证一下求和是否正确
有了增强for,让我们又多了一种方法可以遍历数组和集合,有了可变参数,让我们可以在不确定参数个数的情况下能继续使用方法;这两个新语法看起来比之前的更简洁,可以更方便的实现我们的需要