可以在类和方法中预支地使用未知的类型,一般在创建对象时,将位置类型确定为具体类型,当没有指定泛型时候, 默认类型是Obj类型。
public class GenericDemo {
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("abc");
list.add("def");
// list.add(5); 集合已经明确了具体元素存放的类型
// 已经明确了类型,在使用迭代器的时候,迭代器也同样知道遍历元素的具体类型
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String str = iterator.next();
// 使用iterator()在这里可以直接获取String类型
System.out.println(str.length());
}
System.out.println(list);
}
}
泛型,用来灵活的将数据类型应用到不同类、方法、接口当中。将数据类型作为参数进行传递。
格式
修饰符 class 类名<代表泛型的变量>{
}
使用泛型:在创建对象的时候确定泛型
自定义泛型
public class MyGenericClass<MVP> {
// 没有MVP类型, 在这里代表未知的一种数据类型
// 未来传递什么就是什么类型
private MVP mvp;
public MVP getMvp() {
return mvp;
}
public void setMvp(MVP mvp) {
this.mvp = mvp;
}
}
测试
public class TestGenericDemo {
public static void main(String[] args) {
// 创建一个泛型为String类
MyGenericClass<String> my = new MyGenericClass<>();
my.setMvp("哈登哥");
String mvp = my.getMvp();
System.out.println(mvp);
MyGenericClass<Integer> my2 = new MyGenericClass<>();
my2.setMvp(13);
Integer mvp2 = my2.getMvp();
System.out.println(mvp2);
}
}
格式:
修饰符 <代表泛型的变量> 返回值类型 方法名(参数列表){
}
举个栗子
public class MyGenericMethod {
public <MVP>void show(MVP mvp){
System.out.println(mvp.getClass());
}
public <MVP> MVP show2(MVP mvp){
return mvp;
}
}
测试
public class TestGenericDemo2 {
public static void main(String[] args) {
MyGenericMethod mgm = new MyGenericMethod();
// 在调用方法时, 确定泛型的类型
mgm.show("aaa");
mgm.show(123);
mgm.show(12.45);
}
}
格式
修饰符 interface 接口名<泛型>{
}
举个栗子
public interface MyGenericInterface<E> {
public abstract void add(E e);
public abstract E getE();
}
实现类在定义类的时候确定泛型的类型
public class MyGenericImpl implements MyGenericInterface<String> {
@Override
public void add(String s) {
}
@Override
public String getE() {
return null;
}
}
上面泛型 E 的值就是String类型
public class MyGenericImpl2<E> implements MyGenericInterface<E> {
@Override
public void add(E e) {
}
@Override
public E getE() {
return null;
}
}
确定泛型
public class TestGenericDemo2 {
public static void main(String[] args) {
MyGenericImpl2<String> impl2 = new MyGenericImpl2<>();
ArrayList<Object> list = new ArrayList<>();
impl2.add("hehe");
}
}
常用的通配符含义
<?> 不知道到使用什么类型来接受的时候
public class TestGenericDemo3 {
public static void main(String[] args) {
Collection<Integer> list1 = new ArrayList<>();
Collection<String> list2 = new ArrayList<>();
getElement(list1);
getElement(list2);
}
public static void getElement(Collection<?> coll){
// <?>代表可以接受任意类型
}
}
在Java中的泛型可以指定一个泛型的上限和下限
泛型的上限
:
格式 : 类型名称<? extends 类 > 对象名称
意义 : 只能接受该类型及其子类
泛型的下限
:
格式 : 类型名称<? super 类 > 对象名称
意义 : 只能接受该类型及其父类
举个栗子:现在已知Object类、String类、Number类、Integer类,其中Number类是Integer类的父类
public class TestGenericDemo4 {
public static void main(String[] args) {
Collection<Integer> list1 = new ArrayList<>();
Collection<String> list2 = new ArrayList<>();
Collection<Number> list3 = new ArrayList<>();
Collection<Object> list4 = new ArrayList<>();
getElement1(list1);
getElement1(list2);// 报错
getElement1(list3);
getElement1(list4); // 报错
getElement2(list1)// 报错
getElement2(list2)// 报错
getElement2(list3)// 报错
getElement2(list4)// 报错
}
// 泛型的上限 此时泛型?必须是Number类型或者Number类型子类
public static void getElement1(Collection<? extends Number> coll){
}
// 泛型的下限 此时泛型?必须是Number类型或者Number类型父类
public static void getElement2(Collection<? super Number> coll){
}
}
异常: 指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止
在Java中异常本身是一个类, 产生异常就是创建异常对象并且抛出了一个异常对象。Java处理异常的方式是中断处理
异常不是语法错误, 语法错误是无法通过编译
异常的根类是 java.lang.Throwable,两个子类 java.lang.Error和 java.lang.Exception
平时所说的异常是java.lang.Exception
Throwable体系:
举个栗子
public class Demo1 {
public static void main(String[] args) {
int[] arr = {1, 2, 4};
System.out.println(arr[3]);
}
}
Java中异常处理的五个关键字:try、catch、finally、throw、throws
throw new 异常类名(参数);
举个栗子
throw new NullPointerException("要访问的arr数组不存在");
throw new ArrayIndexOutOfBoundsException("数组越界了,兄弟");
public class Demo2 {
public static void main(String[] args) {
int[] arr = {1, 2, 4, 5};
int index = 4;
int element = getElement(arr, index);
System.out.println(element);
}
public static int getElement(int[] arr, int index){
// 判断
if (index < 0 || index> arr.length-1){
throw new ArrayIndexOutOfBoundsException("数组越界了,兄弟");
}
return arr[index];
}
}
声明异常:将为题标识出来, 报告给调用者, 如果方法内通过throw 抛出了编译时异常, 而没有捕获处理,那么必须通过throws进行声明,让调用者去处理
修饰符 <代表泛型的变量> 返回值类型 方法名(参数列表) throws 异常类1, 异常类2 {
}
举个栗子
public class Demo3 {
public static void main(String[] args) throws ParseException {
String s = "1994-12";
timeFormat(s);
}
public static void timeFormat(String str) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
Date date = sdf.parse(str);
System.out.println(date);
}
}
如果异常出现会立刻终止程序, 所以我们得处理异常
try {
编写可能会出现异常的地方
}catch(异常类型 e){
// 处理异常的代码
// 记录日志、打印异常信息、继续抛出异常
}
public class Demo4 {
public static void main(String[] args) {
try {
read("xiaomiMi.txt");
} catch (Exception e) {
// 在try中抛出什么异常,在括号中就捕获什么异常类型
// e.printStackTrace();
System.out.println("++++++++");
System.out.println(e);
}
System.out.println("end");
}
public static void read(String path) throws FileNotFoundException {
if (!path.equals("xiaomimi.txt")){
throw new FileNotFoundException("你的文件怎么消失了呢");
}
}
}
finally: 有一些特定的代码,无论是否发生异常都要执行,另外,因为异常会引发程序跳转,导致有些语句执行不到, 而finally就解决了这个问题。
public class Demo4 {
public static void main(String[] args) {
try {
read("xiaomiMi.txt");
} catch (Exception e) {
// 在try中抛出什么异常,在括号中就捕获什么异常类型
// e.printStackTrace();
System.out.println("++++++++");
System.out.println(e);
}finally {
System.out.println("不管try和catch执行啥了,我这里都会执行");
System.out.println("我是接盘侠");
}
System.out.println("end");
}
public static void read(String path) throws FileNotFoundException {
if (!path.equals("xiaomimi.txt")){
throw new FileNotFoundException("你的文件怎么消失了呢");
}
}
}
l# ambda表达式
是JDK1.8版本的新特性, lambda 省去面向对象的条条框框,格式由3部分组成
(参数类型 参数名) -> { 代码语句 }
public interface Cook {
void makeFood();
}
public class Demo2 {
public static void main(String[] args) {
invoke(()->{
System.out.println("lambda表达式做的饭好了");
});
}
public static void invoke(Cook cook){
cook.makeFood();
}
}
小括号代表Cook接口的makeFood方法参数为空, 大括号代表makeFood的方法体
需求:使用数组存储多个Person对象,对数组中的Person对象使用Arrays的sort方法通过年龄排序;
代码分析
public class Demo4 {
public static void main(String[] args) {
Person[] array = {
new Person("貂蝉", 223),
new Person("孙尚香", 18),
new Person("妲己", 300),
new Person("杨玉环", 221),
};
Arrays.sort(array, (Person a, Person b)->{
return a.getAge()-b.getAge();
});
for (Person person :array){
System.out.println(person);
}
}
}
public interface Calculator {
int calc(int a , int b);
}
public class Demo5 {
public static void main(String[] args) {
// 使用lambda表达式 调用测试
invokeCalc(5,6, (int a, int b)->{
return a + b;
});
}
public static void invokeCalc(int a, int b, Calculator calculator){
int res = calculator.calc(a, b);
System.out.println("res = "+ res);
}
}
Lambda强调做什么, 而不是怎么做, 凡是可以根据上下文推导得知的消息,都可以省略
public class Demo6 {
public static void main(String[] args) {
// 使用lambda表达式 调用测试
invokeCalc(5,6, (a, b)-> a + b);
}
public static void invokeCalc(int a, int b, Calculator calculator){
int res = calculator.calc(a, b);
System.out.println("res = "+ res);
}
}
省略规则:
public class Demo7 {
public static void main(String[] args) {
// 使用lambda表达式 调用测试
invokeShow(100, a -> a + 100);
}
public static void invokeShow(int a, Show show){
int res = show.showNum(a);
System.out.println(res);
}
}
改写之前厨子
public class Demo8 {
public static void main(String[] args) {
invoke(()-> System.out.println("省略在做饭"));
}
public static void invoke(Cook cook){
cook.makeFood();
}
}
本文地址:https://blog.csdn.net/weixin_39489903/article/details/107681928
如对本文有疑问, 点击进行留言回复!!
浅析IDEA如何正确配置Gradle? GRADLE_USER_HOME 和 Gradle user home的区别
spring boot-2.1.16整合swagger-2.9.2 含yml配置文件的代码详解
有关IntelliJ IDEA中LeetCode插件配置问题
如何在Intellij中安装LeetCode刷题插件方便Java刷题
vscode检测到#include错误请更新includePath的解决方法
IDEA中使用Git拉取代码时报 Git pull failed原因及解决方法
Java8 Stream Collectors收集器使用方法解析
网友评论