1.API
API(Application Progranmming Interface,应用程序编程接口)指就是JDK中提供各种功能的Java类,这些类将底层的实现封装了起来,我们不需要知道这些类是如何实现的,我们只需要学习这些类该如何使用,比如生成随机数、控制台输出等JDK官方的一些类库。我们可以通过帮助文档来学习API的使用方法。
例如,生成一个0~100(包含)以内的整数,代码如下:
public class Test {
public static void main(String[] args) {
// 生成随机数
Random random = new Random();
int i = random.nextInt();//随机生成一个整数
int a = random.nextInt(2);//生成一个0~指定值(不包括)的整数。
System.out.println(i);
System.out.println(a);
}
}
java.lang不需要导包,JDK官方提供的类库都在rt.jar包中。JDK提供了非常多的类库
2.帮助文档的使用
按照帮助文档学习Scanner类的使用,并实现键盘录入一个字符串,输出在控制台。代码如下:
public class Test2 {
public static void main(String[] args) {
//创建Scanner
Scanner sc = new Scanner(System.in);
System.out.println("请录入一个字符串值:");
//接收 用户输入的字符串
String a = sc.nextLine();
System.out.println("你录入的值是:"+a);
}
}
3.Object类
如果类没有继承其它类,那么它默认间接地继承了Object类。默认Object类中是无参构造方法,因此作为父类,其子类默认都是继承了无参构造方法。
Object类中有哪些方法呢?
- ①clone()——克隆方法(复制对象)
- ②equals(Object obj)——比较两个对象是否相等
- ③getClass()——获取该对象的class
- ④hashCode()——返回该对象的哈希值。
- ⑤notify()——唤醒正在此对象监视器上等待的单个线程。
- ⑥notifyAll()—— 唤醒等待此对象监视器的所有线程。
- ⑦toString()——返回对象的字符串表示形式
4.控制台输出对象原理
public class Test2 {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("mayikt");
stu.setAge(22);
// 创建的stu到底什么意思? 可查看java源代码。
System.out.println(stu);
// 结果:该类的完整路径地址@哈希值(@符号仅作拼接显示)
// com.mayikt2.days17.Student@1e643faf
}
}
5.重写Object类的toString方法
toString()方法其目的就是给我们对象重写的,输出对象中所有成员属性值。
//Student类
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//Test2类
public class Test2 {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("mayikt");
stu.setAge(22);
//调用重写后的toString()方法
System.out.println(stu.toString());
}
}
6.String字符串原理
public class Test {
public static void main(String[] args) {
//char只能保存单个字符,而String可保存多个字符(即字符串)。
//String的底层,实质就是通过char数组来保存字符串。
String str = "mayikt";
System.out.println("普通字符串:"+str);
char[] value = {'m','a','y','i','k','t'};
System.out.println(value);
}
}
7.String类的equals方法
7.1 基本概念
equals()方法用于比较两个字符串的值是否相等,相等返回ture,否则返回false。注意,使用该方法时前面的字符串不能为空(null,后面的可以为空),否则会报空指针错误。
public class Test {
public static void main(String[] args) {
String s1 = "mayikt1";
String s2 = "mayikt2";
String s3 = null;
boolean r1 = s1.equals(s2);
boolean r2 = s1.equals(s3);//换成s3.equals(s1)就会报错!
System.out.println(r1);
System.out.println(r2);
}
}
7.2 案例——用户登录
需求:已知用户名和密码,用程序实现模拟用户登录,总共给3次机会,登录之后给出相应提示。
思路:①已知用户名和密码。②键盘输入要登录的用户名和密码,用Scanner。③对已知和输入的内容(字符串)比较,用equals()方法。④用循环实现多次机会(最多3次),可采用for循环;登录成功时,用break结束循环。
代码如下:
//第一步
//方案一,没有实现多次机会
public class login {
public static void main(String[] args) {
//定义正确的用户名和密码
String userName = "admin";
String userPwd = "123456";
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String user = scanner.nextLine();
System.out.println("请输入密码:");
String pwd = scanner.nextLine();
if (userName.equals(user)&&userPwd.equals(pwd)){
System.out.println("用户名和密码正确,登录成功!");
}else {
System.out.println("用户名和密码错误,登录失败!");
}
}
}
//方案二,简单优化,把登录写进方法中
public class Login2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String user = scanner.nextLine();
System.out.println("请输入密码:");
String pwd = scanner.nextLine();
login(user,pwd);
}
public static void login(String user, String pwd){
//定义正确的用户名和密码
String userName = "admin";
String userPwd = "123456";
if (userName.equals(user)&&userPwd.equals(pwd)){
System.out.println("用户名和密码正确,登录成功!");
}else {
System.out.println("用户名和密码错误,登录失败!");
}
}
}
//方案三,进一步优化,使用三元运算符
public class Login3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String user = scanner.nextLine();
System.out.println("请输入密码:");
String pwd = scanner.nextLine();
System.out.println(login(user,pwd)?"用户名和密码正确,登录成功!":"用户名和密码错误,登录失败!");
}
//返回布尔类型
public static boolean login(String user, String pwd){
//定义正确的用户名和密码
String userName = "admin";
String userPwd = "123456";
return userName.equals(user)&&userPwd.equals(pwd);
}
}
//第二步,加上3次机会
public class Login4 {
public static void main(String[] args) {
//定义正确的用户名和密码
String userName = "fumin";
String userPwd = "123456";
//机会次数
int chance = 3;
for (int i = 0; i <chance; i++) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名:");
String user = scanner.nextLine();
System.out.println("请输入密码:");
String pwd = scanner.nextLine();
int remainChance = chance-i-1;
//循环判断
if(userName.equals(user)&&userPwd.equals(pwd)){
System.out.println("用户名和密码正确,登录成功!");
//结束循环
break;
}if(remainChance == 0){
System.out.println("你已3次输错密码,账户已冻结!");
}
else{
System.out.println("用户名和密码错误!您剩余:"+ remainChance +"次机会!");
}
}
}
}
8.Object类的equals方法
Object类中的equals()方法默认是比较两个对象的内存地址是否相同,即直接判断this 和obj本身的值是否相等;只有重写了Object类中的equals()方法后,才能比较两个对象成员属性值是否相同。
注意:双等于号(==)默认也是比较两个对象的内存地址是否相同。
//第一个类Student
public class Student extends Object{
private String name;
private int age;
//构造方法
public Student(){
}
//通过有参构造方法给成员属性赋值
public Student(String name, int age) {
this.name = name;
this.age = age;
}
//重写equals方法,以比较两个成员属性的值
@Override
public boolean equals(Object obj) {
//1.两个对象内存地址相同,this指参数s1,obj指参数s2
if (this==obj){
return true;
}
//2.两个对象类型是否相同
if (obj==null||this.getClass()!=obj.getClass()){
return false;
}
//比较两个对象属性值
//String类型中的equals方法默认是比较属性值的大小。
Student object = (Student) obj;
return this.age==object.age && this.name.equals(object.name);
}
}
//第二个类Test5
public class Test5 {
public static void main(String[] args) {
Student s1 = new Student("mayikt",22);
Student s2 = new Student("mayikt",22);
Mayikt mayikt = new Mayikt();
//没有重写equals方法前,默认比较两个对象内存地址是否相同(结果肯定是false),重写后就是比较两个对象的属性值是否相同了。
System.out.println(s1.equals(s2));
System.out.println(s1.equals(mayikt));
}
}
9.instanceof 关键字
instanceof 通过返回一个布尔值来指出,某个对象是否是某个特定类或该特定类的子类的一个实例。应用于防止类型强转时,程序抛出异常,保证代码的安全性。
如果 ojbect 是 class 的一个实例/实现类,则 instanceof 运算符返回 true。如果 ojbect 不是指定类的一个实例或 object 为 null,则返回 false。class 可以是类,也可以是接口。
instanceof 在Java 的编译和运行阶段有区别。在编译状态,class可以是object对象的父类、自身类、子类,均不会报错。如:cat instanceof AnimalParent(父类)或者cat instanceof Cat(自身类)均不报错。在运行状态,class是object对象的父类、自身类,不能是子类。前两种情况下result的结果为true,最后一种为false。但是class为子类时,在编译阶段不会报错(因为无法识别),但在程序运行阶段就会报错了,运行结果为false。
10.String类的replace方法
public class Test02 {
public static void main(String[] args) {
String str1 = "mayiktmeite1111";
String str2 = "mayiktmeite1111mayiktmeite1111";
//replace -替换指定内容(str1中的“1111”)
String s1 = str1.replace("1111","yushengjun");
System.out.println(s1);
//replaceFirst -替换首次匹配的内容(str2前面部分的“1111”)
String s2 = str2.replaceFirst("1111","ysj");
System.out.println(s2);
}
}
11.String类的split方法
public class Test03 {
public static void main(String[] args) {
String str = "武汉|孝感|北京|上海";
//通过“|”符号(前面加\\作转义,防止出错)分割字符串,并返回数组类型的多个城市。
//注意“|、*、\、^、:、.”符号都要转义。
String[] arrays = str.split("\\|");
System.out.println(arrays[0]);
System.out.println(arrays[1]);
System.out.println(arrays[2]);
System.out.println(arrays[3]);
}
}
12.ASCII码字符对照表
12.1 概念
ASCII码全称“美国信息交换标准代码,”简称“阿斯克码”,其作用是将字母、字符、数字、标点转换成计算机能识别的二进制。记住A和a就行了,其它的可依次推算(十进制)。
字符 | 十进制 | 二进制 |
---|---|---|
A | 65 | 01000001 |
a | 97 | 01100001 |
0 | 48 | 00000000 |
12.2 实例
键盘录入一个字符串,统计该字符串中的大写字母、小写字母和数字出现的次数,不考虑其它字符。
思路:用ASCII码判断。如果是大写字母(A-Z)对应65-90;如果是小写字母(a-z)对应97-122;如果是数字字符(0-9)对应48-57。
代码:
public class Test02 {
public static void main(String[] args) {
/**
* 思路:用ASCII码判断。
* 如果是大写字母(A-Z)对应65-90;
* 如果是小写字母(a-z)对应97-122;
* 如果是数字字符(0-9)对应48-57。
*/
Scanner sc = new Scanner(System.in);
System.out.println("请在下面输入一段字符串,可统计大小写字母和数字出现的次数:");
String str = sc.nextLine();
int bigCount = 0;
int smaCount = 0;
int numCount = 0;
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);//用charAt()方法来获取字符串中的每个字符
if (ch >=65 && ch <=90){
//是大写字母
bigCount++;
} else if (ch >=97 && ch<=122) {
//小写字母
smaCount++;
} else if (ch >=48 && ch<=57) {
//是数字
numCount++;
}
}
System.out.println("大写字母出现的次数为:" + bigCount);
System.out.println("小写字母出现的次数为:" + smaCount);
System.out.println("数字出现的次数为:" + numCount);
}
}
13.indexOf方法
public class Test5 {
public static void main(String[] args) {
String str = "mayiktmeiteAndmeite";
//查找指定字符一次出现的下标(如果没找到则返回“-1”)
System.out.println(str.indexOf("meite"));
//看字符的长度
// System.out.println("mayiktmeite".length());
//从指定的下标(11)开始,查找指定字符(meite)的下标
System.out.println(str.indexOf("meite",11));
}
}
public class Test6 {
public static void main(String[] args) {
//indexOf要查找的字符 也可以是字符的ASCII码
String str = "MaA66";
//例如查找大写字母A(ASCII码为65)的下标
System.out.println(str.indexOf(65));
}
}
14.toLowercase方法
public class Test7 {
public static void main(String[] args) {
String str = "MasaMZ";
System.out.println("将字符串中的大写字母转为小写:"+str.toLowerCase());
System.out.println("将字符串中的小写字母转为大写:"+str.toUpperCase());
}
}
15.String的底层实现
JDK1.8 String类型的底层实现基于char类型数组;而JDK1.9 String类型的底层实现基于byte类型数组。为什么要改呢?答:节省String占用jvm的内存空间。
16.java元空间
JDK1.8之前,称作“方法区、永久代”,JDK1.8开始,称作“元空间”。用于存放静态变量、class信息。new对象均存放在“堆内存”中。JDK1.7开始,字符串常量池 从“方法区”移动到了堆中存放。
17.Math类
17.1 概念
定义了许多执行基本数字运算的方法。它不能创建对象,因为它的构造方法是私有。但可以通过“类名.方法”调用其内部的静态方法。
17.2 常见方法
public class Test1 {
public static void main(String[] args) {
//abs:返回绝对值,结果为13
System.out.println(Math.abs(-13));
System.out.println("------Math.ceil-----");
//ceil:传入一个小数,返回一个比它稍大的整数
System.out.println(Math.ceil(6.6));//结果7.0
System.out.println(Math.ceil(6.0));//结果6.0
System.out.println(Math.ceil(-6.6));//结果-6.0
System.out.println("------Math.floor-----");
//floor:传入一个小数,返回一个比它稍小的整数
System.out.println(Math.ceil(6.6));//结果6.0
System.out.println(Math.ceil(6.0));//结果6.0
System.out.println(Math.ceil(-6.6));//结果-7.
System.out.println("------Math.round------");
//floor:传入一个小数,返回一个四舍五入的整数(int类型)
System.out.println(Math.round(6.6));//7
System.out.println(Math.round(6.3));//结果6
System.out.println("------Math.max/min------");
//max/min:传入2个数字,返回其中较大或较小的那个数
System.out.println(Math.max(6,66));//结果66
System.out.println(Math.min(6,66));//结果6
System.out.println("------Math.pow------");
//pow:传入2个数字a和b,返回a的b次幂(也就是a的b次方)
System.out.println(Math.pow(2,3));//结果8.0
System.out.println("------Math.random------");
//random:不传入数字,随机返回一个0与1之间的数字(不包括1)
System.out.println(Math.random());
//生成一个1~100之间的随机数(包含1和100),下面有2种方式
System.out.println(Math.floor(Math.random()*100+1));
System.out.println((int)(Math.random()*100+1));
}
}
18.System类
System类由final修饰,无法被继承。
public class Test2 {
public static void main(String[] args) {
//exit:终止java虚拟机,0表示正常退出,其它表示异常退出
// System.out.println("正常运行代码");
// System.exit(0);
//currentTimeMillis:获取当前系统时间,从1970/1/1开始计算,以ms为单位。
//1s=1000ms 1min=60s
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
System.out.println("mayikt");
}
long end = System.currentTimeMillis();
System.out.println("执行100000次循环,耗时:"+(end-start)+" 毫秒");
}
}
19.Arrays类(工具类)
19.1 设计思想
①构造方法用private修饰,外部无法new;②成员方法用public static 修饰,可用“类名.方法名”访问;③所有方法均为静态方法。
19.2 常用方法
//sort方法:可将字符类型数组按abc的顺序排列,可将数字类型数组从小到大排列
public class Test4 {
public static void main(String[] args) {
int[] arrs = {44,55,66,77,88};
System.out.println(arrs);//默认是输出内存地址,不能这样写
//调用MayiktArrays中自定义的sort方法,将数组中的数字从大到小排列并输出
MayiktArrays.sort(arrs);
}
}
//toString方法:将数组转化为字符串
public class Test5 {
public static void main(String[] args) {
char[] ch ={'d','c','b','a'};
int[] num ={22,77,11,4,88,55};
Arrays.sort(ch);
Arrays.sort(num);
System.out.println(Arrays.toString(ch));//结果:[a, b, c, d]
System.out.println(Arrays.toString(num));//结果:[4, 11, 22, 55, 77, 88]
}
}
20.基本数据类型包装类
20.1 包装类
用于基本数据类型与字符串之间的转化。每种基本数据类型都对应一个包装类。(提示:除了int和char特殊外,其余的包装类大写第一个字母即可)
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int* | Integer |
long | Long |
float | Float |
double | Double |
char* | Character |
boolean | Boolean |
20.2 实例1:Integer取值范围
public class Test6 {
public static void main(String[] args) {
//int类型的范围(最小和最大值)?使用Integer包装类中的方法计算
//int是基本数据类型,Integer包装了int类型
System.out.println("int最小值:"+Integer.MIN_VALUE);
System.out.println("int最大值:"+Integer.MAX_VALUE);
}
}
20.3 int/boolean 类型转 String 类型— valueOf
public class Test7 {
public static void main(String[] args) {
//通过有参构造方法传递“数字形式”的字符串
Integer a = new Integer("666");
System.out.println(a);
System.out.println("------------");
//Integer包装类中的valueOf方法,可将“数字形式”的字符串转为数字
Integer b = Integer.valueOf("6666");
System.out.println(b);
}
}
public class Test8 {
public static void main(String[] args) {
//1.如何将int类型转化为String类型?
int a = 66;
//方法一:用空字符串与int拼接
System.out.println(""+a);
//方法二:用valueOf方法
String a2 = String.valueOf(a);
System.out.println(a2);
//2.布尔类型转为String类型?
boolean flag = true;
String f = String.valueOf(flag);
System.out.println(f);
}
}
20.4 String类型转int/boolean类型
public class Test9 {
public static void main(String[] args) {
//1.String → int
//将String转化为int,注意只有数字形式的String才能转化!
String str = "123";
//方法一:valueOf与intValue一起用
Integer num = Integer.valueOf(str);
System.out.println(num);
//如果要直接返回int类型呢?
int num1 = num.intValue();
System.out.println(num1);
System.out.println("-----分割线------");
//方法二:parseInt一步到位(常用)
int num2 = Integer.parseInt(str);
System.out.println(num2);
//2.String → boolean
String flag = "true";//注意,如果String的值不是boolean值(true/false),转换后的值永远为false
boolean b1 = Boolean.parseBoolean(flag);
System.out.println(b1);
System.out.println("---分割---");
//3.String → double
String s = "6.66";
double d = Double.parseDouble(s);
System.out.println(d);
}
}
20.5 基本数据类型与包装类型的区别
①以int与Integer为例,int属于基本数据类型,而Integer属于类,是一个对象。②基本数据类型存放在栈空间中,而包装类存放在堆空间中。(所有对象和数组存放在堆中)③基本数据类型的默认值为0/false,而包装类的默认值为null。④输出包装类时,底层会调用toString方法,实际输出基本数据类型的值。⑤基本数据类型为值传递,包装类为引用传递。
提示:实际开发中,包装类比基本类型更常用。
20.6 装箱和拆箱
装箱:自动将基本数据类型转换为包装类型。拆箱自动将包装类型转换为基本数据类型。
Integer i = 5;//装箱
int j = i;//拆箱
public class Test12 {
public static void main(String[] args) {
/**
* 小案例:字符串中的数据排序
* 对字符串"97,16,36,18,50"中的数字从小到大排序,再输出。
*/
String str ="97,16,36,18,50";
//1.分割字符串,转化为int类型数组
String[] s1 = str.split(",");//用“,”分割字符串里的数字
int[] s2 = new int[s1.length];
for (int i = 0; i < s1.length; i++) {
s2[i] = Integer.parseInt(s1[i]);
}
//2.对int数组排序,再输出
Arrays.sort(s2);
for (int i = 0; i < s2.length; i++) {
if (i != s2.length - 1){
System.out.print(s2[i]+",");
}else {
System.out.print(s2[i]);
}
}
}
}
21.Date类
21.1 构造方法
//分配一个Date对象,初始化时间(当前时间),精确到毫秒。
public Date();
//分配一个Date对象,表示从标准时间起指定的毫秒数。
public Date(Long date);
//实例1
public class Test02 {
public static void main(String[] args) {
//注意:使用Date类时,要引入java.util.Date,不要错误地引入到java.sql.Date中
Date date1 = new Date();
System.out.println(date1);
//结果:Wed Aug 07 09:08:12 CST 2024(CST表示“中国标准时间”)
System.out.println("-----------");
//GMT(格林威治时间)
long time = 1000 * 60 * 60;//代表1小时
Date date2 = new Date(time);
System.out.println(date2);
//结果:1970-1-1 0:00:00 + 8小时(中国是+8区) +1小时 = 1970-1-1 9:00:00
}
}
21.2 常用方法
//获取日期对象,从1970年1月1日0:00:00到现在的毫秒数,也叫“时间戳”。
public long getTime();
//设定时间,毫秒数。
public void setTime(Long time)
//实例2
public class Test03 {
public static void main(String[] args) {
//getTime()
Date date1 = new Date();
long t1 = date1.getTime();//获取1970-1-1 0:00:00到现在的毫秒数。
System.out.println(t1);
System.out.println("-----------");
//setTime()
long t2 = 1000*60*60;//表示:一小时
date1.setTime(t2);//在1970-1-1 0:00:00的基础上,增加“t2”个小时。
System.out.println(date1);
//结果:Thu Jan 01 09:00:00 CST 1970(即1970-1-1 9:00:00)
}
}
21.3 格式化日期
SimpleDateFormat用于格式化和解析日期。作用有:①对时间日期格式化处理;②把Date对象转化为“年月日时分秒”格式字符串;③把字符串转化为Date对象。
字母 | 含义 |
---|---|
y | 年,如yyyy |
M | 月,如MM |
d | 日,如dd |
h | 时(12小时制) |
H | 时(24小时制) |
m | 分,如mm |
s | 秒,如ss |
yyyy年M月dd日 | 2024年8月10日 |
//1.把Date对象转化为日期字符串:format()
public class Test04 {
public static void main(String[] args) {
//创建一个日期对象
Date date = new Date();
System.out.println(date);
//结果:Sat Aug 10 08:54:12 CST 2024
//对创建的日期格式化,使其更加美观
//创建一个格式对象
SimpleDateFormat date1 = new SimpleDateFormat("yyyy年MM月dd日 H:mm:ss");
System.out.println(date1.format(date));
//结果:2024年08月10日 8:54:12
}
}
//2.把日期字符串转化为Date对象:parse()
public class Test05 {
//日期字符串转为Date类型,需要抛出异常
public static void main(String[] args) throws ParseException {
//创建一个需要格式化的日期字符串
String dt = "2024年08月10日 8:54:12";
//创建SimpleDateFormat对象,对其格式化(注意格式要与日期字符串一致,否则无法转换)
SimpleDateFormat dt1 = new SimpleDateFormat("yyyy年MM月dd日 H:mm:ss");
System.out.println(dt1.parse(dt));
//结果:Sat Aug 10 08:54:12 CST 2024
}
}
21.4 日期工具类的设计
//1.先创建一个DateUtil工具类
public class DateUtil {
private static final String FORMAT_1 = "yyyy-MM-dd HH:mm:ss";//常量变量名必须大写(这是规范)
//先将构造方法私有化,这样就可以直接通过类名访问,不需要再创建对象(下面是一个无参构造方法)
private DateUtil() {
}
//常用方法
//Date转String方法
public static String DateToString(Date date,String format) {
SimpleDateFormat formatter = new SimpleDateFormat(format);
return formatter.format(date);
}
//String转Date方法
public static Date StringToDate(String date,String format) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat(format);
return formatter.parse(date);
}
//获取当前系统时间,直接转化为String类型
public static String getCuDateString() {
return DateToString(new Date(),FORMAT_1);
}
}
//2.在Test06类中调用
public class Test06 {
public static void main(String[] args) throws ParseException {
//1.调用DateUtil中的Date转String方法
String d1 = DateUtil.DateToString(new Date(), "yyyy-MM-dd HH:mm:ss");
System.out.println(d1);
//结果:2024-08-10 09:42:57
//2.调用DateUtil中的String转Date方法(要手动抛出一个字符串异常)
Date d2 = DateUtil.StringToDate("2024-08-10 09:39:48","yyyy-MM-dd HH:mm:ss");
System.out.println(d2);
//结果:Sat Aug 10 09:39:48 CST 2024
//3.调用DateUtil中的"获取当前系统时间,直接转化为String类型"方法
String s3 = DateUtil.getCuDateString();
System.out.println(s3);
//结果:2024-08-10 10:01:14
}
}
22.Calendar日历类
22.1 获取系统时间
public class Test07 {
public static void main(String[] args) {
//获取Calender对象,多态机制(因为抽象类不能创建对象)
Calendar c = Calendar.getInstance();
System.out.println(c);
//结果:java.util.GregorianCalendar[time=1723258789560,areFieldsSet=true,areAllFieldsSet=true,lenient=true,
// zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,
// transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2024,MONTH=7,
// WEEK_OF_YEAR=32,WEEK_OF_MONTH=2,DAY_OF_MONTH=10,DAY_OF_YEAR=223,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=2,AM_PM=0,
// HOUR=10,HOUR_OF_DAY=10,MINUTE=59,SECOND=49,MILLISECOND=560,ZONE_OFFSET=28800000,DST_OFFSET=0]
System.out.println("------------");
//获取年
int year = c.get(Calendar.YEAR);
//获取月,从0开始,因此实际要+1
int month = c.get(Calendar.MONTH)+1;
//获取日
int day =c.get(Calendar.DAY_OF_MONTH);
System.out.println("当前的日期为:"+year+"年"+month+"月"+day+"日");
//结果:当前的日期为:2024年8月10日
}
}
22.2 修改获取的系统时间
public class Test08 {
public static void main(String[] args) {
//Calendar常用方法
Calendar c = Calendar.getInstance();
//修改获取的系统日期,使用.add()方法,正数为增加,负数为减少
c.add(Calendar.YEAR,1);//在当前年份的基础上,增加1年
c.add(Calendar.MONTH,-1);//在当前月份的基础上,减1个月
c.add(Calendar.DAY_OF_MONTH,5);//在当前日的基础上,加5天
//直接修改成你想要的日期,使用.set()方法
c.set(2060,8,8,12,30,00);//年月日时分秒,可以只设置一部分
//获取年
int year = c.get(Calendar.YEAR);
//获取月,从0开始,因此实际要+1
int month = c.get(Calendar.MONTH)+1;
//获取日
int day =c.get(Calendar.DAY_OF_MONTH);
System.out.println("当前的日期为:"+year+"年"+month+"月"+day+"日");//这里最小只获取到日
}
}
22.3 小案例:2月有多少天
public class Test09 {
public static void main(String[] args) {
//需求:键盘录入一个年份,可以显示其2月有多少天,并判断该年是闰年还是平年?
//注意:平年的2月是28天,闰年的2月是29天
System.out.println("请在下方输入一个年份:");
Scanner sc = new Scanner(System.in);
int sc1 = sc.nextInt();
//创建日期对象,多态机制
Calendar c = Calendar.getInstance();
//修改年月日为:输入的年,3月,1日
c.set(sc1,2,1);//因为月是从0开始算,所以2代表3月
//在3月1日的基础上减去1天,就到了2月最后一天
c.add(Calendar.DAY_OF_MONTH,-1);
//获取日
int day = c.get(Calendar.DAY_OF_MONTH);
System.out.println(sc1+"年的2月有:"+day+"天");
System.out.println(day==28?sc1+"年是平年":sc1+"年是闰年");
}
}
23.异常
23.1 定义
程序执行报错或出现了不正常现象。JVM默认情况下,如果执行报错,会直接中断,后面的代码不会再执行。
public class Test01 {
public static void main(String[] args) {
int[] arr = {1,2,3};
System.out.println(arr[4]);
//ArrayIndexOutOfBoundsException: 越界异常
User user = null;
user.addUser();
//NullPointerException:空指针异常(因为你没有new出来对象,没有调用方法)
}
}
23.2 异常处理
//1.语句:try...catch...
//2.格式:
try{
可能出现异常的代码;
}catch(异常类名 变量名){
异常处理的代码;
}
//3.执行流程:
出现异常时,会生成一个异常类对象。Java运行并收到异常对象时,会到catch中找匹配的异常类,并做相应处理,程序还可继续往下执行,不会因为异常而中断。但如果没有在catch中找匹配的异常类依然会中断代码的执行哦。
//4.实例:
public class Test03 {
public static void main(String[] args) {
System.out.println("代码开始");
try{
//运行一段可能有问题的代码
a1();
}catch(Exception e){
//捕获异常
System.out.println("你访问的数组下标越界了!");
e.printStackTrace();//在程序结尾显示异常的类型和位置(可省略)
}
System.out.println("代码结束");
}
public static void a1(){
int[] arr = {8,9,10};
System.out.println(arr[3]);
}
}
//5.Throwable的成员方法
public String getMessage:返回此throwable详细消息字符串。
public String toString:返回此可抛出的简短描述。
public void printStrackTrace()将异常信息输出到控制台。
//java中的两类异常处理
public class Test06 {
/**
* java中 异常分为2类
* 1.编译时异常,.java源代码 编译成.class文件 之间发生的异常,必须处理否则无法编译。
* 2.运行时异常,编译成.class文件后,在运行时发生的异常,不一定要处理。
*/
public static void main(String[] args) throws Exception{
a1();
a2();
a3();
a4();
}
//Exception包括了编译异常和运行时异常,前者必须throws或者try...catch处理。
public static void a1() throws Exception{
int[] arr = new int[3];
System.out.println(arr[4]);//数组下标越界异常
}
public static void a2() throws Exception{
}
public static void a3() throws Exception{
}
//调用a4()方法时,不需要在main方法后throws Exception或在该调用时用try...catch捕获异常,因为ArrayIndexOutOfBoundsException属于运行时异常,可以不做处理。
public static void a4() throws ArrayIndexOutOfBoundsException{
}
}
23.3 自定义异常
//1.自定义一个login异常类(用于抛出编译时异常)
public class LoginException extends Exception {
//本类继承了Exception父类,因此可抛出编译时异常
//创建一个登录异常的有参构造方法,将异常内容传到父类去
public LoginException(String message) {
super (message);
}
}
//2.在Test08类中调用
public class Test08 {
/**
* 注意:用throws处理异常时,异常下面的代码将不会执行;而用try...catch捕获异常时,异常下面的代码还可执行。
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception{
Scanner sc = new Scanner(System.in);
System.out.println("请在下方输入用户名:");
String userName = sc.nextLine();
System.out.println("请在下方输入密码:");
String pwd= sc.nextLine();
login(userName,pwd);
}
public static void login(String userName, String pwd) throws Exception{
if(!(userName.equals("admin") && pwd.equals("123456"))){
//如果用户输入的名字和密码不正确就抛出异常,提示不正确
throw new LoginException("你输入的用户名或密码不正确!");
}
System.out.println("用户名和密码正确,登录成功!");
}
}
//3.如果想自定义一个login异常类用于抛出运行时异常,只需要改为继承RuntimeException父类即可。需要注意的是,该异常不强制要用try...catch来捕获,也可正常运行(这点与编译时异常不同)。
暂无评论内容