1 代码块
类的构成:
- 成员变量
- 常量
- 类变量(static)
- 构造方法(重载)
- 成员方法
- 静态方法
- 成员内部类
1.1.分析main:
public static void main(String[] args) {
}
调用者:jvm
public : 保证了方法的访问权限足够大
static:保证了方法的加载时机 可以不需要对象就能访问
void:返回值的存在没有意义
main:名称就是方便jvm去使用 因此是固定
String[] args:main是可以接收参数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SOxxi5So-1627907425036)(assest/image-20210723090938580.png)]
1.2 代码块
1.2.1 构造代码块
public class Student {
private String name;
private int age ;
//代码块 使用大括号括起来的一段代码
{
System.out.println("代码块执行......");
}
public Student() {
System.out.println("无参构造执行....");
}
public Student(String name, int age) {
System.out.println("带参构造执行......");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student stduent = (Student) o;
return age == stduent.age && Objects.equals(name, stduent.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Stduent{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N9LI2meC-1627907425038)(assest/image-20210723092046410.png)]
代码块随着对象的创建而执行。每创建一个对象 就会执行依次 而且他的执行时机优先于构造方法。
代码块可以对成员变量进行初始化
通常也将代码块称为构造代码块
1.2.2 静态代码块
static{
System.out.println("静态代码块....");
}
1 随着类的加载而加载
2 执行时机是最早 优先执行(优先于构造代码块和构造方法)
静态中不能使用this
1 this表示对象
2 static 在加载的时候 还没有对象存在
静态只能使用静态 非静态既可以使用静态 也可以使用非静态
3 静态代码块可以完成对静态变量的初始化
静态代码块 > 构造代码块 > 构造方法
2.jdk中的常用API
2.1 Math
Math
类包含执行基本数字运算的方法,如基本指数,对数,平方根和三角函数。
通过API文档的查阅,我们发现Math类中的变量和方法的声明都是static 意味着对于这些变量和方法的调用,不需要创建对象 ,可以直接通过类型.的方式来调用
random()
返回值为 double
值为正号,大于等于 0.0
,小于 1.0
。
public class MathTest {
public static void main(String[] args) {
for(int i = 0 ; i < 10;i++){
double random = Math.random();
System.out.println(random);
}
}
}
产生的随机数是[0.0,1.0)
产生一个0–10之间的随机数
public static void main(String[] args) {
for(int i = 0 ; i < 10;i++){
int random = (int)(Math.random() *10);
System.out.println(random);
}
}
产生3-8之间的随机数
public class MathTest {
public static void main(String[] args) {
for(int i = 0 ; i < 10;i++){
int random = (int)(Math.random() *5) + 3 ;
System.out.println(random);
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZKJsOO1g-1627907425042)(assest/image-20210723095028007.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3iGafoHF-1627907425044)(assest/image-20210723095037992.png)]
2.2 Random
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ijTOFQ6s-1627907425045)(assest/image-20210723095210678.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WY44wLYg-1627907425046)(assest/image-20210723095242490.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hYguskuN-1627907425047)(assest/image-20210723095254585.png)]
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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-THaXhj69-1627907425047)(assest/image-20210723101947333.png)]
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);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bkoC5j2o-1627907425048)(assest/image-20210723102226626.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bczIgxNC-1627907425049)(assest/image-20210723102238913.png)]
2.4 包装类
基本类型的包装类
java语言是面向对象的语言
为了弥补java设计中的8基本类型不满足面向对象思想缺陷,同时便于在开发中对基本数据类型的数据进行相关的操作,因此引入了八种基本类型所对应的类。这个类就称为基本类型的包装类。
八种基本类型对应的包装类
基本类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
Byte Short Integer Long Float double 他们都是Number的子类 都是数字型
public abstract class Number
在Number类中 提供了可以将包装类转换为基本类型的方法。intValue();longValue() ;floatValue()。。。
2.4.1 Integer
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lZtXPMHC-1627907425049)(assest/image-20210723103534340.png)]
构造方法:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vqIzGyjz-1627907425050)(assest/image-20210723103552665.png)]
方法
将Integer转换为基本类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lVZmWR2F-1627907425050)(assest/image-20210723103641917.png)]
获取两个整数中的最大值和最小值
将字符串解析为基本类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I5spSYJR-1627907425051)(assest/image-20210723103717998.png)]
将基本类型转换为字符串
将基本类型转换为包装类
public class IntegerTest {
public static void main(String[] args) {
// Integer integer = new Integer("100");//表明这个方法过时了 有新的方法取代了他 不推荐使用,但是依然还可以使用
//Integer integer = new Integer(100);//过时;
Integer integer1 = 100;
Integer integer2 = Integer.parseInt("100");
Integer integer3 = Integer.valueOf(100);
Integer integer4 = Integer.valueOf("100");
}
}
Integer和int的区别:
Integer类型的对象可以调用Integer中所定义的方法 ,对整数进行相应的处理和操作
而int基本类 型 是没有这些操作的
反映出提供基本类型的包装类的好处。
2.4.2 int和String之间的相互转换
基本类型的包装类的常见操作就是完成基本类型和字符串之间的相互转换,已经对应的基本类型和其他基本类型之间的相互转换
1 int 转换为String
方式一:使用String类提供的valueOf
方式二:
String s = i1 +"";
直接在数字后边加上一个空字符串
2,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 输出结果
public class IntegerDemo {
public static void main(String[] args) {
// 1 定义一个字符串“23,45,67,88,21,44”
String s = "23,45,67,88,21,44";
// 2 把字符串中的数字存储到一个int类型的数组中
// 此时需要首先的到字符串中的每一个数值
String[] strArr = s.split(",") ;
//
// 对字符串数组进行遍历,将每一个元素转换为int类型 parseInt()
// 3 先定义一个int数组,将解析得到的值保存在一个int数组中
int[] arr = new int[strArr.length];
for(int i = 0 ; i <arr.length;i++){
arr[i] = Integer.parseInt(strArr[i]);
}
// 4 对数组进行排序
Arrays.sort(arr);
// 5 对int数组进行遍历 字符串的拼接采用StringBuilder
StringBuilder sb = new StringBuilder();
sb.append("\"");
for(int i = 0 ; i <arr.length;i++){
if(i == arr.length -1 ){
sb.append(arr[i]);
}else{
sb.append(arr[i] + " " );
}
}
sb.append("\"");
// 6 输出结果
System.out.println(sb.toString());
}
}
2.4.3 自动装箱和自动拆箱
自动装箱和自动拆箱就是将基本类型和包装类之间进行像话转换。jdk1.5之后 引入的。
自动装箱: 可以将基本类型直接赋值给对应的包装类 jvm会自动将基本类型的数据转换为对应的包装类的对象 ,而且这种转换是自动完成的,所以称为自动装箱
自动拆箱:就是和自动装箱相反的过程
Integer i1 = 100;//自动装箱
int ii1 = i1;//自动拆箱
2.4.4 包装类的缓存问题
整型 char 所对应的包装类在自动装箱的同时,对于-128~127 之间的值会进行缓存处理,目的就是提高效率
Ineger的源码
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
1 IntegerCache为Ineger类的静态内部类,仅供Integer类使用
2 缓存范围是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
代表一个特定的时间 精确到毫秒
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xsBgLmUh-1627907425056)(assest/image-20210723112818760.png)]
时间的表示:GMT 格林尼治时间
UTD 协调世界时间
中国标准时间:CST
3.2 常用方法
toString()
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
是一个具体的类,用于以区域设置敏感的方式格式化和解析日期。 它允许格式化(日期文本),解析(文本日期)和归一化。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hszHjk8l-1627907425058)(assest/image-20210723113823185.png)]
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对象
获取制定字段
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:因为编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。
如: 空指针异常 读物的文件不存在 网络连接中断 数据下标越界
对于程序出现的错误,一般有两种解决方法:
1 遇到错误就终止程序的运行。
2 有开发者在编程中,针对可能出现的问题,即使的增加检测和错误信息的提示以及针对特定错误做出相应的处理。
异常通常分为:编译期异常和运行期异常
5.2.1 运行时异常
是在编译器不要求强制处置的异常,一般啊是指在编程时的逻辑错误,是程序应该积极避免其出现的异常
5.2.2. 编译期异常
是编译器要求必须处置的异常,即程序在运行时由于外界因素造成的一般性异常,编译器要求java程序必须进行相应的处理,否则程序无法正常运行。
5.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就采用默认的处理方式:
1 在控制台打印堆栈信息
2 终止程序执行。
throws抛出异常的特点:
抛的是异常的类型(在try–catch中捕获的是异常的对象);
抛出异常可以抛出多个异常类型(在try–catch中捕获的时候 只能捕获一个异常对象)
5.5 自定义异常
一般情况下 自定义异常自定的是运行时异常 也可以是编译期异常
如果要自定义运行时异常 则自定义异常只需要继承RuntimeExcepetion即可
如果要定义一个编译期异常 则只需要继承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区别:
1编写的位置: throw 在方法的内部
throws 在方法的声明上
2 抛出的类型 throw 抛出的是一个对象
throws 抛出的是异常的类型
3 抛出的个数 throw 抛一个对象
throws 可以抛出多个类型