Java基础知识1----基本概念(2)

本文详细介绍了Java中的泛型,包括类型擦除和通配符的使用。接着探讨了反射机制,解释了如何获取和操作类的组件,并强调其在破坏封装性和破坏泛型约束性方面的应用。此外,文章还讲解了注解的定义、自定义注解、元注解以及注解解析,并提到了动态代理的概念和实现。在异常处理部分,阐述了异常的分类、默认处理机制以及如何进行编译时和运行时异常的捕获和处理。最后,简单提及了I/O流和BigDecimal在处理高精度计算时的作用。

1. 泛型

1.1 Java 泛型了解么?什么是类型擦除?介绍一下常用的通配符?

  1. 泛型:参数化类型,也就是所有操作的数据类型被指定为一个参数。提供编译时类型安全检测机制,能够检测到非法类型。
  2. 类型擦除:Java 的泛型是伪泛型,这是因为 Java 代码编译阶段,所有的泛型信息都会被擦掉
  3. 泛型使用方式:泛型类、泛型接口、泛型方法。
  4. 常用的通配符为: T,E,K,V,? 区别:
    没有区别,知识约定好的特定类型
    ? 表示不确定的 Java 类型
    T (type) 表示具体的一个 Java 类型
    K V (key value) 分别代表 Java 键值中的 Key Value
    E (element) 代表 Element
  5. 通配符的种类
    无限定通配符-Unbounded Wildcard <?> :能够装入任意类型
    上限通配符-Upper Bounded Wildcard:必须是指定Number类型或指定Number类型的子类。<? extends Number>
    下限通配符-Lower Bounded Wildcard:必须是 Integer 类或 Integer 类的父类—<? super Integer>
  6. List,List,List<?>的区别 List :指定的类,可以通过实例化进行传入 List:指定的类,Object List<?>:不能进行操作。 ? car = getCar()。不合法

2. 反射:

  1. 什么是反射?
    1)对于任意一个Class类,在“运行的时候”,都可以直接得到这个类的全部成分;这种运行时动态获取类信息以及动态调用类成分的能力叫做Java语言的反射机制。
  2. 反射的关键是什么?
    1)反射的第一步是获取编译后的Class类对象,然后可以得到Class的全部成分
    (1):Class c1=Class.forName(“全类名”)已知类的文件名,获取类(静态方法获取,用的最多)
    (2):Class c2=类名.class :已知类名,获取类(最安全)
    (3):Class c3=对象.getClass() :已知类的实例对象,获取类
  3. 反射的作用
    0)破坏封装性
    1)反射获取构造器对象:用于创建类对象(如果是私有构造器,也能够打开,所以会破坏封装性)
    2)反射获取成员变量对象(私有成员变量可以通过暴力打开权限):用于在某个对象中取值和赋值。
    3)反射获取方法方法对象(私有方法可以通过暴力打开权限):用于在某个对象中触发方法。
    4)绕过编译阶段给集合添加数据,没有泛型的约束了。
  4. 总结反射的作用
    1)可以在运行时得到一个类的全部成分然后操作
    2)可以破坏封装性(很突出)
    3)可以破坏泛型的约束性(很突出)
    4)更重要的用途:做Java高级框架
    5)基本上主流框架都会基于反射设计一些通用的技术功能。

3. 注解

3.0 注解的作用

  1. Java语言中的类,构造器,方法,成员变量和参数都可以被注解进行标注
  2. 进行标记,然后会进行特殊的处理。

3.1 自定义注解

  1. 自己定义的注解,注解名称和功能自己写;
  2. 通过元注解注解自己注解的使用范围和生命周期,这是一定要写的。
  3. 然后使用反射的原理,把注解给解析了。通过反射去取注解,如果是一定的注解,那么就实现一定的功能。

3.2 元注解

注释注解的注解,主要就两类

  1. @Target:使用范围:约束自定义注解只能在哪些地方使用
  2. @Retention:申明注解的生命周期。

3.3 注解解析

  1. 定义:注解的解析就是判断是否存在注解,存在注解就解析出内容
  2. 类型
    1)比如注解在成员方法上面,则现货区成员方法Methods对象,然后再拿上面的注解,实现具体的功能。
  3. 注解的应用实例
    1)junit框架就是一个,主要用于测试书写的方法。(启动时,会被触发执行)

3.4 动态代理

  1. 定义:代理是被代理者没有能力或者不愿意去完成某件事,需要找个人替自己去完成。
  2. 关键步骤
    1)必须有接口,实现类要实现接口(代理通常是基于接口实现的)
  1. 创建一个实现类对象,该对象为业务对象,然后再为业务对象做一个代理对象。
  1. 动态代理的优点
    1)非常灵活,支持任意接口类型的实现类对象做代理
    2)可以为被代理对象的所有方法做代理
    3)可以在不改变源码的情况下,实现对方法功能的增强
    4)简化了编程工作,提高了软件系统的可扩展性,同时也提高了开发的效率。(切面编程思想)

4. 异常

4.1 什么是异常,为什么要学习异常

  1. 什么是异常
    1):异常是程序在编译或者执行的过程中可能出现的问题。注意:语法错误不属于异常体系
    2):举例:数组索引越界,空指针异常,日期格式化异常
  2. 为什么需要学习异常
    1)异常一旦出现,没有处理的话,会使得JVM虚拟机停止运行
    2)研究异常和避免异常,能够使得程序更加安全和稳健。

4.2 异常的体系

  1. 异常属于Throwable接口,下分有两个,一个是Error,属于操作系统出现错误,不再考量范围内
  2. 另一个接口为Exception,有两类需要格外注意
    (1):RuntimeException及其子类:编译时不报错,但是运行时报错,原因是程序员水平不行,代码写的有问题。
    (2):除了RuntimeException及其子类:编译时就报错,主要目的是提醒程序员,这一块比较容易出错,需要格外注意。

4.3 运行时异常

  1. 概念:直接继承自RuntimeException及其子类,编译阶段不报错,运行时报错
  2. 举例
    (1)数组索引越界异常:ArrayIndexOutOfBoundsException
    (2) 空指针异常:NullPointerException
    (3)数学操作异常:ArithmeticException
    (4)类型转换异常:ClassCastExcetion
    (5)数字转换异常:NumberFormatException
  3. 错误原因:自己代码编写水平有问题

4.4 编译时异常

  1. 概念:不是直接继承自RuntimeException及其子类,编译阶段就报错
  2. 举例
    (1)日志解析异常
  3. 错误原因:担心程序员水平不行,提醒一下,可遇而不可求

4.5 异常的默认处理机制

  1. 创建异常对象:默认在出现异常的地方常见一个异常对象
  2. 抛给调用者,抛给虚拟机:异常会从方法出现的点连续向外面抛出
  3. 输出异常栈:虚拟机接收到异常后,在控制台直接输出异常栈的信息数据
  4. 干掉程序:程序会被迫停止,后面的程序也运行不了

评价:默认的异常处理机制并不好,一旦真的出现异常,程序会立即死亡

4.6 编译时异常处理机制

4.6.1 抛出去:出现异常直接抛出去给调用者,调用者也继续抛出去:

  1. 核心使用方法throws:将方法内部出现的异常抛给本方法的调用者处理
  2. 缺点:异常方法如果自己不处理,那么就会抛给虚拟机,使得程序死亡
  3. 抛出的两种途径:
//方式一:对象为方法,能抛出指定的异常
方法  throws  异常一,异常二,异常三..{
   方法的内容
}
//方式二:对象为方法,能抛出所有的异常
方法  throws Exception{
   方法的内容
}

4.6.2 捕获处理:出现异常自己捕获处理,不麻烦人

  1. 核心方法:try…catch…:
  2. 抛出的两种格式
//方式一:并不怎么规范```
try{  
//监控可能出现异常的代码
}catch(异常类型1 变量){   
    //处理异常
}catch(异常类型2 变量){   
    //处理异常
}...
//方式二:规范格式
try{  
	//监控可能出现异常的代码
}catch(Exception 变量){   
    e.printStackTrace();   //直接打印异常栈的信息,可以捕获所有异常
}

4.6.3 两者结合,出现异常直接抛出去给调用者,调用者捕获处理。

  1. 前两个抛出方法问题:对于方法一,直接抛出异常,会使得程序马上进行死亡状态 ;对于方法二,会使得调用者不知道哪里出现了异常。
  2. 两者结合的方法
    1)在方法中调用异常抛出
    2)在调用者处进行捕获处理

4.7 运行时异常处理机制

一般情况是不需要处理异常的,但是可以建议在最外层调用处集中捕获处理即可。

4.8 自定义异常

5. I/O流

6. 重要知识点

6.1 反射机制详情?

6.2 Java代理模式详情

设计模式–代理模式:

  1. 定义:使用代理对象来代替真实对象的访问,可以在不修改原目标对象的前提下,提供额外的功能。
  2. 功能:扩展目标对象的功能,在方法执行前后增加功能。
  3. 实现方法:静态代理和动态代理
  4. 静态代理的步骤:
  5. 动态代理的步骤:
  6. 静态和动态代理的区别:

6.3 IO模型详情

  1. I/O:输入输出
    1)计算机结构角度:
    I/O描述了计算机系统 与外部设备之间的通信过程
    2)应用程序角度:
    用户进程通过向系统请求系统调用,操作系统间接访问内核空间,完成数据的交换。
  2. 常见的I/O模型:
    同步阻塞I/O,同步非阻塞I/O,异步I/O和I/O多路复用和信号驱动I/O
    1)同步阻塞I/O–BIO (Blocking I/O)
    定义:应用程序发起read调用后,会一直阻塞,直到内核把数据拷贝到用户空间去。
    缺点:并发程度不高,一旦数据量大,很难操作
    2)同步非阻塞I/O
    定义:通过轮询操作,一次次请求read调用,避免了一直阻塞。
    缺点:系统调用轮询数据是否已经准备好的过程是十分消耗CPU资源。
    3)I/O 多路复用模型 ----NIO (Non-blocking/New I/O)
    定义:线程先发起select调用,看是否内核数据已经准备好了,用户线程再发起read调用,NIO引入有一个多路复用器,一个线程能够管理多个客户端。
    优点:相比同步非阻塞,通过使用select调用,减少无效的系统调用。降低CPU压力。
    4)异步I/O—AIO (Asynchronous I/O)
    发起请求,直接返回,后台处理,通知回调。
    5)总结:
    BIO:客户端发起请求,应用程序阻塞等待,直到处理完成。
    NIO:线程通过选择器可以监听多个客户端,客户端发起select调用,看是否准备就绪,然后发起请求。
    AIO:客户端发起请求,直接返回,后台处理,通知回调。
    6)形象的比喻
    (1) BIO:同步阻塞,我去访问一个人家里(read操作),他没在家,我在门口一直等
    (2) NIO: 同步非阻塞,我去访问一个人家里(read操作),发现他没在家,我先回去,然后隔一段时间就去一次。
    (3) NIO 多路复用(同步非阻塞),在他家装了一个监控,发现他回家了(select操作),电话联系某一个等待的人,让他去他家(read操作)
    (4) AIO:异步非阻塞,直接去他家,留下一封信,信上面交代要处理的事情,然后直接回去,主人回来后看见性处理问题,并且寄出回信。

6.4 BigDecimal 详解

  1. 功能:为了避免精度丢失,采用bigdecimal进行解决。

  2. 为什么浮点数 float 或 double 运算会有精度丢失的风险呢?
    浮点数没有办法用二进制精确表示,因此存在精度丢失的风险。

  3. 解决办法:
    直接使用 BigDecimal 来定义浮点数的值,再进行浮点数的运算操作即可。

  4. BigDecimal的常用方法:
    新建对象:BigDecimal a = new BigDecimal(“1.0”);
    加减乘除:add;abstract; multiply; divid;
    大小比较:a.compareTo(b): -1 ; 0 ; 1
    保留几位小数:setScale

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值