1 代码块
- 类的构成
- 成员变量
- 常量
- 类变量(static)
- 构造方法(重载)
- 成员方法
- 静态方法
- 成员内部类
1.1 分析main方法:
public static void main(String[] args){
}
调用者:jvm
public: 保证方法的访问权限足够大
static: 保证方法的加载时机 可以不需要对象就能访问
void : 返回值的存在没有意义
main:名称就是方便jvm去使用 因此是固定的
String[] args:main方法是可以接收参数的
1.2 代码块
代码块:使用大括号括起来的一段代码
1.2.1 构造代码块
** 随着对象的创建而执行,每创建一个对象,就会执行一次,而且他的执行时机优先于构造方法 **
代码块可以对成员变量进行初始化
通常也将代码块称为构造代码块
1.2.2 静态代码块
static{
System.out.println("静态代码块....");
}
-
随着类的加载而加载
-
执行实际最早 优先执行(优先于构造代码块和构造方法)
- 静态中不能使用this
- this 表示对象
- static 在加载时,还没有对象存在
- 静态只能使用静态,非静态可以静态也可以非静态
-
代码块可以完成对静态变量的初始化
静态代码块>构造代码块>构造方法
2 jdk中常用的API
2.1 Math
math类包含执行基本数字运算的帆帆发,如基本指数、对对胡
static double | E double值比其他任何一个都更接近 e ,自然对数的基数。 |
---|---|
static double | PI double值比任何其他的更接近 pi ,圆周长与其直径的比率。 |
一些方法:
static double | abs(double a) 返回值为 double绝对值。 |
---|---|
static float | abs(float a) 返回 float值的绝对值。 |
static int | abs(int a) 返回值为 int绝对值。 |
通过API文档的查阅,我们发现Math中的变量和方法的声明都是static的,在调用这些变量和方法时,不需要创建对象,可以直接用类型.
的方法调用
static float | max(float a, float b) 返回两个 float的较大值。 |
---|---|
static int | max(int a, int b) 返回两个 int值中的较大值。 |
static double | random() 返回值为 double值为正号,大于等于 0.0 ,小于 1.0 。 |
// 产生位于区间[0.0,10)的随机数
public class MathTest {
public static void main(String[] args) {
for(int i = 0 ; i < 10;i++){
double random = Math.random();
System.out.println(random);
}
}
}
2.2 Random 类
构造方法
Random()
创建一个新的随机数生成器。
Random(long seed)
使用单个 long种子创建一个新的随机数生成器。
boolean | nextBoolean() 返回下一个伪随机数,从这个随机数发生器的序列中均匀分布 boolean值。 |
---|---|
void | nextBytes(byte[] bytes) 生成随机字节并将它们放入用户提供的字节数组中。 |
double | nextDouble() 返回下一个伪随机数,从这个随机数发生器的序列中 0.0和 1.0之间的 double值 0.0分布。 |
float | nextFloat() 返回下一个伪随机数,从这个随机数发生器的序列中 0.0和 1.0之间的 float值 0.0分布。 |
int | nextInt() 返回下一个伪随机数,从这个随机数发生器的序列中均匀分布 int值。 |
int | nextInt(int bound) 返回伪随机的,均匀分布 int值介于0(含)和指定值(不包括),从该随机数生成器的序列绘制。 |
long | nextLong() 返回下一个伪,均匀分布 long从这个随机数生成器 |
public class RandomTest {
public static void main(String[] args) {
Random r = new Random();
for(int i = 0 ; i < 10 ; i++){
int ran = r.nextInt();//-2的31次方 到 2的31次方减一
System.out.println(ran);
}
System.out.println("----------------------");
for(int i = 0 ; i < 10 ; i++){
int ran = r.nextInt(10);// 产生一个0--bound之间的整数 bound随机数的上限
System.out.println(ran);
}
System.out.println("----------------------");
for(int i = 0 ; i < 10 ; i++){
int ran = r.nextInt(10) +20;// 产生20--30之间的随机数
System.out.println(ran);
}
}
}
2.3 System
static void | exit(int status) 终止当前运行的Java虚拟机。 |
---|---|
static long | currentTimeMillis() 返回当前时间(以毫秒为单位)。 |
static void | arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 将指定源数组中的数组从指定位置复制到目标数组的指定位置。 |
for(int i = 0 ; i < 10 ; i++){
int ran = r.nextInt(10);// 产生一个0--bound之间的整数 bound随机数的上限
if(ran == 5 ){
System.exit(-1);// 终止jvm运行
}
System.out.println(ran);
}
2.4 包装类
基本类型的包装类
Java语言是面向对象的语言,
为了弥补Java设计中的八个基本类型不满足面向对象的思想缺陷,同时便于开发中对基本数据类型的数据进行相关操作,因此引入了八种相应的类。这个类就被称为基本类型的包装类
基本类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
Byte Short Integer Long Float Double
都是Number的子类,都是数字型
在Number类中 提供了可以将包装类转换成基本类型的方法。
intValue();
longValue() ;
floatValue();
……
2.4.1 Integer
static int | MAX_VALUE 一个持有最大值一个 int可以有2的31次方 -1。 |
---|---|
static int | MIN_VALUE 的常量保持的最小值的 int可以具有,-2的 31次方。 |
构造方法:
Integer(int value)
//构造一个新分配的 Integer对象,该对象表示指定的 int值。
Integer(String s)
//构造一个新分配 Integer对象,表示 int由指示值 String参数。
方法:
int | intValue() 将 Integer的值作为 int 。 |
---|
- 获取两个整数间的最大值或最小值:
static int | max(int a, int b) 返回两个 int的较大值,就像调用 Math.max一样 。 |
---|---|
static int | min(int a, int b) 返回两个 int的较小值,就像调用 Math.min一样 。 |
- 将字符串解析为基本类型:
static int | parseInt(String s) 将字符串参数解析为带符号的十进制整数。 |
---|
- 将基本类型转换成字符串:
String | toString() 返回 String表示此对象 Integer的价值。 |
---|---|
static | String toString(int i) 返回一个 String指定整数的 String对象。 |
- 将基本类型转换成包装类:
static Integer | valueOf(int i) 返回一个 Integer指定的 int值的 Integer实例。 |
---|---|
static Integer | valueOf(String s) 返回一个 Integer对象,保存指定的值为 String 。 |
Integer和int的区别:
Integer类型的对象可以调用Integer中所定义的方法 ,对整数进行相应的处理和操作
而int基本类 型 是没有这些操作的
反映出提供基本类型的包装类的好处。
2.4.2 int和String之间的相互转换
基本类型的包装类的常见操作就是完成基本类型和字符串之间的相互转换,已经对应的基本类型和其他基本类型之间的相互转换
- int 转换为String
方式一:使用String类提供的valueOf
static String | valueOf(boolean b) 返回 boolean参数的字符串 boolean形式。 |
---|---|
static String | valueOf(char c) 返回 char参数的字符串 char形式。 |
static String | valueOf(char[] data) 返回 char数组参数的字符串 char形式。 |
static String | valueOf(char[] data, int offset, int count) 返回 char数组参数的特定子阵列的字符串 char形式。 |
static String | valueOf(double d) 返回 double参数的字符串 double形式。 |
static String | valueOf(float f) 返回 float参数的字符串 float形式。 |
static String | valueOf(int i) 返回 int参数的字符串 int形式。 |
static String | valueOf(long l) 返回 long参数的字符串 long形式。 |
static String | valueOf(Object obj) 返回 Object参数的字符串 Object形式。 |
方式二:
String s = i1 +""; //直接在数字后边加上一个空字符串
- String和int之间的转换
方式一:
Integer.valueOf(String s)
可以将String类型转换为Integer
然后使用Integer的intValue() 将Ineger转换为int类型
方式二:
将一个字符串类型的数值解析为基本类型
练习: 有一个字符串 “23,45,67,88,21,44”请编写程序实现最终的输出输出结果为 “21 23 44 45 67
88”思路:
1 定义一个字符串“23,45,67,88,21,44”
2 把字符串中的数字存储到一个int类型的数组中
此时需要首先的到字符串中的每一个数值
对字符串数组进行遍历,将每一个元素转换为int类型 parseInt()3 先定义一个int数组,将解析得到的值保存在一个int数组中
4 对数组进行排序
5 对int数组进行遍历 字符串的拼接采用StringBuilder
6 输出结果
2.4.3 自动装箱和自动拆箱
就是将基本类型和包装类进行类型转换 jdk1.5之后引入
自动装箱:就是将基本类型赋值给对应的包装类 jvm 会自动将基本类型的数据 转换成 对应的包装类的对象,而这种转换是自动完成的,所以称为自动装箱
自动拆箱:就是和自动装箱相反的过程
Integer i1 = 100;//自动装箱
int ii1 = i1;//自动拆箱
2.4.4 包装类的缓存问题
整型 char 所对应的包装类在自动装箱的同时,对于-128~127 之间的值会进行缓存处理,目的就是提高效率
Integer的源码
-
IntegerCache为Ineger类的静态内部类,仅供Integer类使用
-
缓存范围是IntegerCache.low(-128) ~IntegerCache.high(127)
public static void main(String[] args) {
Integer i1 = 100;//自动装箱
Integer i2 = 100;
System.out.println(i1 == i2);//true
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3 == i4);//false
}
3 时间日期类
3.1 Date
代表一个特定的时间,精确到毫秒
Date() | 分配一个 Date对象,并初始化它,以便它代表它被分配的时间,测量到最近的毫秒。 |
---|---|
Date(long date) | 分配一个 Date对象,并将其初始化为表示自称为“时代”的标准基准时间以后的指定毫秒数,即1970年1月1日00:00:00 GMT。 |
时间的表示:
GMT 格林尼治时间
UTD 协调世界时间
CST 中国标准时间
3.2 常用方法
long | getTime() 返回自1970年1月1日以来,由此 Date对象表示的00:00:00 GMT的毫秒 数 。 |
---|---|
String | toString() 将此 Date对象转换为 String的形式 |
public class DateTest {
public static void main(String[] args) {
Date d1 = new Date();
System.out.println(d1);// 获取系统当前时间 Fri Jul 23 11:32:28 CST 2021
Date d2 = new Date(1000*60*60); //Thu Jan 01 09:00:00 CST 1970
System.out.println(d2);
//常用方法:
System.out.println(d1.getTime());//获取date表示的日期距离1970年1月1 00:00:00的毫秒数
Long dd2 = d2.getTime();
System.out.println(dd2);
}
}
3.3 时间格式化
SimpleDateFormat
是一个具体的类,用于以区域设置敏感的方式格式化和解析日期。 它允许格式化(日期文本),解析(文本日期)和归一化。
public static void main(String[] args) {
Date d1 = new Date();
// SimpleDateFormat sdf = new SimpleDateFormat();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String strDate = sdf.format(d1);
System.out.println(strDate);
}
格式化的本质:就是将一个Date类型的日期转换成了String类型的日期
日期的解析:将一个字符串类型的日期 解析成Date类型的日期
public static void main(String[] args) throws ParseException {
Date d1 = new Date();
// SimpleDateFormat sdf = new SimpleDateFormat();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String strDate = sdf.format(d1);
System.out.println(strDate);
String str = "2021-7-22 11:42:32";
Date date = sdf.parse(str);//日期的解析
System.out.println(date);
}
解析异常:
解析的特殊情况:
/*
工具类:
1 具有通用性 和普遍适用性
2 工具类中的方法 通常都是static
*/
public class DateUtils {
private DateUtils(){
}
//1 对Date进行格式换 将Date转换为了String
public static String date2String(Date date,String format){
SimpleDateFormat sdf =new SimpleDateFormat(format);
String strDate = sdf.format(date);
return strDate;
}
// 2 String类型的日期 解析为Date
public static Date str2Date(String strDate,String format) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date d = sdf.parse(strDate);
return d;
}
}
public class DateUtilTest {
public static void main(String[] args) throws ParseException {
//获取系统当前日期
Date date = new Date();
String s1 = DateUtils.date2String(date,"yyyy-MM-dd hh:mm:ss");
String s2 = DateUtils.date2String(date,"yyyy/MM/dd hh:mm:ss");
String s3 = DateUtils.date2String(date,"yyyy年MM月dd hh:mm:ss");
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
String strDate = "2020-11-11 16:30:23";
Date d1 = DateUtils.str2Date(strDate,"yyyy-MM-dd hh:mm:ss");
System.out.println(d1);
}
}
3.4 Calendar类
获取Calendar对象
static Calendar | getInstance() 使用默认时区和区域设置获取日历。 |
---|---|
static Calendar | getInstance(Locale aLocale) 使用默认时区和指定的区域设置获取日历。 |
static Calendar | getInstance(TimeZone zone) 使用指定的时区和默认语言环境获取日历。 |
static Calendar | getInstance(TimeZone zone, Locale aLocale) 获取具有指定时区和区域设置的日历。 |
获取指定的字段:
int | get(int field) 返回给定日历 |
---|
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+ 1;// 月份的表示是从0--11
int day = c.get(Calendar.DAY_OF_MONTH) ;
int houre = c.get(Calendar.HOUR_OF_DAY );
int min = c.get(Calendar.MINUTE);
int sec = c.get(Calendar.SECOND);
System.out.println(year +"-"+month+"-"+day+" "+houre+":"+min+":"+sec);
}
public static void main(String[] args) {//设置固定日期
Calendar c = Calendar.getInstance();
c.set(2020,11,11,12,12,12);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+ 1;// 月份的表示是从0--11
int day = c.get(Calendar.DAY_OF_MONTH) ;
int houre = c.get(Calendar.HOUR_OF_DAY );
int min = c.get(Calendar.MINUTE);
int sec = c.get(Calendar.SECOND);
System.out.println(year +"-"+month+"-"+day+" "+houre+":"+min+":"+sec);
}
需求:获取任意一年的二月有多少天
思路:
1 键盘录入年份
2 设置年月日
3 获取3月1 往前推一天
4 输出结果
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
Scanner sc = new Scanner(System.in);
System.out.println("请输入你要获取的年份:");
int year = sc.nextInt();
c.set(year,2,1);//设置日历为当年的3月1日
c.add(Calendar.DATE,-1);//将系统当前日期 往前减一天
int date = c.get(Calendar.DATE);
System.out.println(year+"年的2月份有"+date+"天");
}
4 BigDecimal
BigDecimal 用来对超过16位有效位的数进行精确地运算
双精度浮点型变量double 可以处理16位有效数,在实际应用中,需要对更大的或者更小的数进行运算和处理
float和double只能用来做科学计算或者是工程计算,在商业计算中,一定要使用BigDecimal。
1 创建对象
BigDecimal(int val)
将int
成BigDecimal
。BigDecimal(String val)
将BigDecimal的字符串表示BigDecimal
转换为BigDecimal
BigDecimal(double val)
将double
转换为BigDecimal
,这是double
的二进制浮点值的精确十进制表示。(不建议)
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal(0.1);
System.out.println(bd1);//0.1000000000000000055511151231257827021181583404541015625
BigDecimal bd2= new BigDecimal("0.1");//推荐使用字符串来创建浮点数的Bigdecimal对象
System.out.println(bd2);
}
2 方法
BigDecimal add(BigDecimal augend)
返回BigDecimal
,其值是(this + augend)
,其标为max(this.scale(), augend.scale())
。subtract(BigDecimal subtrahend)
返回BigDecimal
,其值是(this - subtrahend)
,其标为max(this.scale(), subtrahend.scale())
multiply(BigDecimal multiplicand)
返回BigDecimal
,其值是(this × multiplicand),
其标为(this.scale() + multiplicand.scale())
。divide(BigDecimal divisor)
返回BigDecimal
,其值为(this / divisor)
,优先级为(this.scale() - divisor.scale())
; 如果不能表示确切的商(因为它具有非终止的十进制扩展),则抛出一个ArithmeticException
。
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal(0.1);
System.out.println(bd1);//0.1000000000000000055511151231257827021181583404541015625
BigDecimal bd2= new BigDecimal("0.1");//推荐使用字符串来创建浮点数的Bigdecimal对象
System.out.println(bd2);
BigDecimal bd3 = new BigDecimal(17);
BigDecimal bd4 = new BigDecimal(4);
BigDecimal add = bd3.add(bd4);
BigDecimal sub = bd3.subtract(bd4);
BigDecimal mul = bd3.multiply(bd4);
BigDecimal div = bd3.divide(bd4,1, RoundingMode.HALF_EVEN );
System.out.println(add);
System.out.println(sub);
System.out.println(mul);
System.out.println(div);
}
5 异常
5.1 异常概述
异常:就是在程序执行过程中,发生的不正常情况(开发中语法错误和逻辑错误不属于异常)
5.2 异常的分类
Error:Java虚拟机无法解决的严重问题。如:jvm系统内部错误 资源耗尽等严重的情况。一般不用出来
Exception:因为编程错误或 偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理
如: 空指针异常 读物的文件不存在 网络终端等
对于程序出现的错误,一般有两种解决方法:
- 遇到错误就终止程序的运行
- 有开发者在编程中 ,针对可能出现的问题,及时的增加检测和错误信息的提示以后及时针对错误做出相应的处理
异常通常分为: 编译期异常 和 运行期异常
5.2.1 运行时异常
是在编译器不要求强制处置的异常,一般是指在编程时的逻辑错误,时程序应该积极避免其出现的异常
5.2.2 编译时异常
是 编译器要求必须处置的异常 ,即程序在运行时由于外界因素造成的一般性的异常,编译器要求Java编译器必须进行相应的处理,否则程序无法正常运行
5.2.3 常见的异常
一般说的异常指Exception
RuntimeException:
- ArithmeticException:
- ClassCastException
- IndexOutOfBoundsException
- NullPointerException
Excpetion子类:
- ParseException
String[] strArr = {"aa","bb","cc"};
System.out.println(3/0);//ArithmeticException
// System.out.println(strArr[3]);//下标越界异常
strArr = null;
System.out.println(strArr.length);//空指针异常
5.4 异常处理机制
Java中的异常处理采用抓抛模型。
5.4.1 处理机制一
try{
有可能发生异常的代码
}catch(异常类型 变量){
发生时应对异常的代码
} finally{
无论是否发生异常 都会执行的代码
}
public static void main(String[] args) {
String[] strArr = {"aa","bb","cc"};
try{
strArr = null;
System.out.println(strArr.length);//空指针异常
System.out.println(strArr[3]);//下标越界异常
System.out.println(3/0);//ArithmeticException
}catch (ArithmeticException ae){
System.out.println(ae.getMessage());
}catch (ArrayIndexOutOfBoundsException ae){
ae.printStackTrace();
}catch (RuntimeException re){
System.out.println("运行时异常");
}
}
在处理异常的时候,catch可以有多个 可以同时捕获的异常,但是如果存在捕获的异常为继承关系,父类一定是处于最后
try{
strArr = null;
System.out.println(strArr.length);//空指针异常
System.out.println(strArr[3]);//下标越界异常
System.out.println(3/0);//ArithmeticException
}catch (ArithmeticException | ArrayIndexOutOfBoundsException | NullPointerException ae){//jdk7以后的写法 只能是同级别的异常
System.out.println(ae.getMessage());
}
// 面试题
public class ExceptionDemo {
public static void main(String[] args) {
int i = test();
System.out.println(i);//30
}
public static int test(){
int i = 10;
try{
i= i +10;
System.out.println(i/0);
return i;
}catch (Exception e){
i = i+10;
return i;
}finally {
i = i +10;
return i;//finally块的return 会将try块中的return的值覆盖掉
}
}
5.4.2 处理机制二
声明抛出异常:throws
public static Date str2Date(String strDate,String format) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date d = sdf.parse(strDate);
return d;
}
当一个方法抛出异常时,那么这个异常就会抛给方法调用者,作为方法的调用者,则需要选择对于该方法存在的异常的处理方式:抓、抛
层层外抛,直到main抛给jvm ,此时jvm就采用默认的处理方式:
- 在控制台打印对战信息
- 终止程序运行
throws抛出异常的特点:
- 抛出的异常的类型(在try—catch中捕获的时异常的对象)
- 抛出异常可以抛出多个异常类型(在try–catch中捕获的时候只能捕获一个异常对象)
5.5 自定义异常
一般情况下 自定义异常自定的是运行时异常 也可以是编译期异常
如果要自定义运行时异常 则自定义异常只需要继承RuntimeException即可
如果要定义一个编译期异常 则只需要继承Exception即可
自定义异常的实现:
-
定义一个无参构造 在其中使用super调用父类的无参构造
-
定义带参构造 使用错误描述信息作为参数 调用父类的带参构造即可
public class MyException extends Exception{
public MyException(){
super();
}
public MyException(String msg){
super(msg);
}
}
public class MyExceptionTest {
public void regist(int num) throws MyException {
if(num < 0 ){
throw new MyException("人数为负,不符合要求");//在代码内部手动抛出一个异常 是我们自定义异常的对象
}else{
System.out.println("注册成功");
}
}
public void manager(){
try {
regist(-100);
} catch (MyException e) {
e.printStackTrace();
}
System.out.println("注册操作结束");
}
public static void main(String[] args) {
MyExceptionTest my = new MyExceptionTest();
my.manager();
}
}
throw和throws的区别:
- 编写的位置:throw在方法内部 throws 在方法的声明
- 抛出的类型 :throw抛出的是一个对象 throws抛出的是异常的类型
- 抛出的个数:throw 抛出的是一个对象 throws可以抛出多个类型