将一些常用的类归结在一起:
1.字符串相关的类
String类及常用方法,StringBuffer,StringBuilder(写算法推荐使用
)
2.JDK 8之前的日期时间API
Systen静态方法,Date类,Calendar类,SimpleDateFormat类
3.JDK 8中新日期时间API(主张日后使用)
LocalDate,LocalTime,LocalDateTime,Instant,DateTimeFormatter,其他类
4.Java比较器(bool型无法比价,之前对象是无法去进行比较。现在可以通过比较器去比较对象的大小)
Comparable接口,Comparator接口
5.System类
6.Math类
7.BigInteger与BigDecimal
一.字符串相关的类
(1):
String实现不同的接口,所以相对来讲特性不同。底层将String修饰成了一个final的数组,所以String是不可修改的。
我们不妨看一看jdk中String的源码,截取其中的一小段去进行分析:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
private final char value[];
:String是一个不可变的字符序列。
String:字符串,使用一对""引起来表示
1.String声明为final,不可能被继承
2.String实现了Serializable(可序列化)接口:表示字符串支持序列化
序列化:它是处理对象流的一种机制,即可以很方便的保存内存中java对象的状态,同时也为了方便传输
实现了Comparable(可比较的)接口,String可以去比较大小
3.String内部定义了final char[] value用于存储字符串序列
4.String代表不可变的字符串序列,简称:不可变性
体现:1.当给字符串重新赋值的时候,需要重新指定内存区域去进行赋值,不使用原有的value数组去进行赋值。
2.当对现有的字符串进行连接操作时,需要去进行重新指定内存区域赋值,不能使用原来内存区域的字符串。
5.通过字面量的方式给字符串赋值,如果字面量是相同的。那么对象的地址是相同的,此时字符串的值声明在字符串常量池中
,需要区别于new的方式。
6.字符串常量池是不会存储相同内容的字符串的,也就是字面量看到的值。
JVM内存划分图:
ps:方法区中的常量池是不会存放相同的字符串的
代码:
String s1="abc";
String s2="abc";
的内存结构
将s1赋值为hello,新的内存结构如下:
这里还要去介绍其他的情况:
(1)如果s3=“abc”;使用字符串拼接,那么新的字符串会在方法区的常量池里重新进行生成。
String s4="abc";
String s5=s4.replace('a','m');
System.out.println(s5);
(2)虽然s4中的a被替换成m,但是新生成的字符串在方法区的常量池中任然会重新在新的地址去生成字符串。其实还是去根据定义来,字符数组是final去进行修饰的,是不可改变的。
String是一个不可修改的字符序列。
**(2):
**String对象的创建
1.直接从字面量去进行赋值
2.通过new去进行赋值
ps:前面两种,创建之后在内存中分布的位置不同
Question:以下两种方式创建字符串的区别
String str1="abc";
String str2=new String("abc");
答:(1)字符串常量存储在字符串常量池**,目的是共享
。字面量赋值的方式,字符串存储在方法区的常量池当中。一定要注意共享这个词。
(2)字符串非常量对象存储在堆**空间当中(记住一句话,new的产物都是在堆空间去进行开辟)。堆空间不共享,我们各自new出新的对象,你用你的,我用我的。
用一段代码举例子:
@Test
//String 实例化的方式
public void test2(){
String str1="abc";
String str2="abc";
String str3=new String("abc");
String str4=new String("abc");
System.out.println(str1);
System.out.println(str2);
//我们很容易起去判断出,他们的地址是否相同
System.out.println(str1==str2);
System.out.println(str1==str3);
System.out.println(str3==str4);
}
输出结果如下:
在举一个栗子:
Person类的代码如下:
package com.atguig.java;
/**
* @author shkstart
* @create 2020-07-25-15:33
*/
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
}
@Test
public void Test3(){
Person p1=new Person("tom",12);
Person p2=new Person("tom",12);
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true
}
执行过程,内存分配如下:
又问:
通过String s=new String(“abc”);的方式去创建对象的时候,在内存中创建了几个对象?
两个!:一个是在堆空间new的结构,另外一个是char[]定义的常量池中的数据。
又问:
通过String s1=new String(“abc”);
String s2=new String(“abc”);
的方式去创建对象的时候,在内存中创建了几个对象?
三个:堆空间中new的结构是有两个,公用方法区中的常量池一个。
再来看一个问题:
@Test
public void Test4(){
String s1="javaEE";
String s2="hadoop";
String s3="JavaEEhadoop";
String s4="JavaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="JavaEE"+s2;
String s7=s1+s2;
System.out.println(s3==s4);
System.out.println(s3==s5);
System.out.println(s3==s6);
System.out.println(s3==s7);
System.out.println(s5==s7);
System.out.println(s6==s7);
}
输出的结果是什么?请说出原因:
结论:
常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
只要其中有一个是变量,结果就在堆中
如果拼接的结果调用intern()方法
,返回值就在常量池中
以上String基本给讲清楚了。
因为刚刚才买了《深入理解java虚拟机》,看了第二章,理论偏多,这里暂且不摘除理论部分了。
我们虚拟接的版本通常是HotSpot的。通常有三种虚拟机。我的《深入理解java虚拟机》还没看看完,这里暂且不看去看了
JDK 1.6的版本,在字符串常量池在方法区中。
JDK 1.7的版本,在字符串常量池在堆中。
JDK 1.8的版本,在字符串常量池在方法区中。具体体现在元空间
(2)String类相关的API:
int length():返回字符串的长度: return value.length
char charAt(int index): 返回某索引处的字符return value[index]
boolean isEmpty():判断是否是空字符串:return value.length == 0
String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写
String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写
String trim():返回字符串的副本,忽略前导空白和尾部空白
boolean equals(Object obj):比较字符串的内容是否相同
boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写
String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”
int compareTo(String anotherString):比较两个字符串的大小
String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。
String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字
符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。
以上方法的测试用例以及举例:
@Test
public void test1(){
String s1="abcdefg";
String s2="ABDIISD";
String s3="";
String s4="abcdefg";
String s5=" a b c d e f g ";
String s6="AbCdEfG";
System.out.println(s1.length());
System.out.println(s1.charAt(5));//指定索引上的元素
System.out.println(s1.toUpperCase());//只不过是改变后的副本
System.out.println(s2.toLowerCase());
System.out.println(s3.isEmpty());
System.out.println(s1.equals(s4));//true
//trim的用处:输出账号密码的时候
System.out.println(s5.trim());//去除字符串首尾的空格
System.out.println(s1.equalsIgnoreCase(s6));
System.out.println(s1.concat(s2));//字符串连接
System.out.println(s1.compareTo(s2));//比较两个字符串的大小
System.out.println(s1.substring(2));
System.out.println(s1.substring(2,4));
}
执行结果如下:
boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true
int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
@Test
public void test4(){
/**
* boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
* boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
* boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
*/
String str1="helhelloworld";
boolean flag= str1.endsWith("world");//看看字符串是否以world结尾
System.out.println(flag);
System.out.println(str1.startsWith("hel"));
//toffset:从什么位置开始
System.out.println(str1.startsWith("hel",3));
}
int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
注:indexOf和lastIndexOf方法如果未找到都是返回-1
@Test
public void test5(){
/**
* boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列
* 时,返回 true
* int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
* int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出
* 现处的索引,从指定的索引开始
* int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
* int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后
* 一次出现处的索引,从指定的索引开始反向搜索
* 注:indexOf和lastIndexOf方法如果未找到都是返回-1
*/
String str="nimasilenibabasile";
System.out.println(str.contains("nima"));//str存在了这个子串
System.out.println(str.contains("nibaya"));//不存在这个子串
System.out.println(str.indexOf("nima"));//nima的起始位置是0
//指定索引位置开始,看第一次出现字符串的位置
//从位置三开始,没找到字符串为nima的字符串
System.out.println(str.indexOf("nima",3));
System.out.println(str.lastIndexOf("nima"));
//返回字符串出现的最后一次的索引
System.out.println(str.lastIndexOf("nima",5));
}
String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
String replace(CharSequence target, CharSequence replacement):使
用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
String replaceAll(String regex, String replacement) : 使 用 给 定 的replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
String replaceFirst(String regex, String replacement) : 使 用 给 定 的replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。
String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。
String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
这里可能涉及正则表达式,因为我还没有学到,但是一直听人说比较有用,之后有时间一定会去补上。
(3)String类:String与基本数据类型转换
字符串 -->基本数据类型、包装类
Integer包装类的public static int parseInt(String s):可以将由“数字”字符组成的字符串转换为整型。
类似地,使用java.lang包中的Byte、Short、Long、Float、Double类调相应的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型。
/**
* String与基本数据类型和包装类的转换
*
* String-->基本数据类型和包装类的转换
*/
@Test
public void test(){
String str="123";
//如何将str->int
//int num=(int)str;
//提示的错误是无法转换
//String-->基本数据类型和包装类的转换:(注:格式要对,否则无法转换)
// 调用包装类的静态方法,parseXxx(str)
//使用包装类去进行转换
int num=Integer.parseInt(str);
System.out.println(num);
//基本数据类型和包装类-->String:
// (1)调用String重载的valueOf(xxx)
//(2)后面添加一个"",也可以去进行转化
String str1=String.valueOf(num);
String str2=num+"";
System.out.println(str1);
System.out.println(str2);
System.out.println(str1==str2);//在内存中的位置是不同的
}
基本数据类型、包装类–>字符串
调用String类的public String valueOf(int n)可将int型转换为字符串相应的valueOf(byte b)、valueOf(long l)、valueOf(float f)、valueOf(double d)、valueOf(boolean b)可由参数的相应类型到字符串的转换
@Test
/**
* String 与char[] 之间的转换
*/
public void Test2(){
String str1="abc123";
//String-->char[]
char[] arr=str1.toCharArray();
for (int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
}
@Test
/**
* char[]-->String 之间的转换
*/
public void test3(){
char[] arr=new char[]{'h','e','l','l','o'};
String str=new String(arr);
System.out.println(str);
System.out.println(arr.length);
}
在这里插入代码片
字符串–>字节数组
public byte[] getBytes() :使用平台的默认字符集将此 String 编码为byte 序列,并将结果存储到一个新的 byte 数组中。
public byte[] getBytes(String charsetName) :使用指定的字符集将 此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。
/**
* String-->byte[]之间的转换
* String--->byte[]:调用String的getBytes()
*/
@Test
public void test4(){
String str1="123abc";
byte[] b=str1.getBytes();
//输出的都是ASCII码
//如果是汉字的话,就会转换成相应的编码集
String str2="987fed中国";
byte[] by=str2.getBytes();//这里默认为UTF-8
//但是里面的参数可以设置为gbk
System.out.println(Arrays.toString(by));
System.out.println(Arrays.toString(b));
}
编码:字符串-->字节(看得懂-->看不懂)
解码:字节-->字符串(看不懂-->看得懂)
字节数组 -->字符串
String(byte[]):通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
String(byte[],int offset,int length) :用指定的字节数组的一部分,即从数组起始位置offset开始取length个字节构造一个字符串对象。
(4)StringBuffer(太重要了,可以提升输入输出速度)
一定要了解他的工作原理:
- 源码分析:
-
String str1=new String();//new char[0]
-
String str2=new String(“abc”)/new char[3]{‘a’,‘b’,‘c’};
-
StringBuffer sb=new StringBuffer();//sb是空的,但是底层长度设置固定了
-
(ps:new char[16],底层创建了一个长度为16的定长数组,char[] value=new char[16])
-
sb.append(‘a’);//value[0]=‘a’;
-
sb.append(‘b’);//value[1]=‘b’;
-
//建议看一看StringBuffer的源码
-
StringBuffer sb1=new StringBuffer(“abc”);
-
这里输出的长度为3
-
(底层创建了一个长度为sb1.length()+16的定长数组,char[] value=new char[“abc”.length()+16])
-
问题一:sout(sb1.length())---->就是表面输出的长度
-
问题二:扩容问题:如果要添加的数组底层盛不下了,那么就要扩容底层的数组
-
默认情况下,扩容为原来容量的2倍+2,同时将原数组中的元素复制到新的数组当中
建议:开发中建议使用StringBuffer(int capacity) or StringBuilder(int capacity)
-
@Test
public void Test1(){
StringBuffer stringBuffer=new StringBuffer("abc");
//根据索引,更换索引下的字符
stringBuffer.setCharAt(0,'m');
//记住stringBuffer是可变序列,设置之后内容就发生了改变
System.out.println(stringBuffer);
StringBuffer stringBuffer1=new StringBuffer("abcded");
stringBuffer1.setCharAt(0,'a');
System.out.println(stringBuffer1);
System.out.println(stringBuffer1.length());
System.out.println();
StringBuffer stringBuffer2=new StringBuffer();
//空的StringBuffer输出的值为0
System.out.println(stringBuffer2.length());//输出的值为0
}
相关API:StringBuffer类的常用方法
StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
StringBuffer delete(int start,int end):删除指定位置的内容
StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把当前字符序列逆转
/*
StringBuffer类的常用方法
StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
StringBuffer delete(int start,int end):删除指定位置的内容
StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把当前字符序列逆转
*/
@Test
public void Test2(){
//常用方法使用
StringBuffer sb1=new StringBuffer("abc");
StringBuffer sb2=new StringBuffer("def");
StringBuffer sb3=sb1.append(sb2);
System.out.println(sb3);
sb1.delete(2,5);
System.out.println(sb1);
System.out.println();
StringBuffer sb4=new StringBuffer();
sb4.append(1);
sb4.append("1abc");
System.out.println(sb4);
sb4.delete(2,4);//左开右开
System.out.println(sb4);
//字符区间替换,替换成新的字符串
sb4.replace(1,2,"abc");
System.out.println(sb4);
//字符串倒转
sb4.reverse();
System.out.println(sb4);
}
执行结果如下:
总结:
增:append(xxx)
删:delete(int start,int end)
改:replace(int staet,int end,String str)//截图字符串去进行修改
setCharAt(int n,char ch);//修改单个字符
查:charAt(int n)
插:insert(int offset,xxx);
长度:.length()
遍历:for-each/toString()
在效率上:StringBuilder>StringBuffer>>String
但是折中来讲StringBuffer是比较提倡的。
在这里基本上介绍完了String相关类的字符串,因为刚刚才买了《深入理解java虚拟机》,看了一点点,后期会再讲一讲字符串与JVM的联系。
继续前一篇的讲解,现在继续讲一讲日期类的API
二.JDK 8之前**的日期时间API
·
1. java.lang.System类
System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
此方法适于计算时间差。(从1970到现今)
@Test
public void Test1(){
//1.System类中的currentTimeMillis()
long time=System.currentTimeMillis();
System.out.println(time);
//输出的值是1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
//称为一个时间戳
}
2. java.util.Date类
表示特定的瞬间,精确到毫秒
构造器:
(空参数)Date():使用无参构造器创建的对象可以获取本地当前时间。
(有参数)Date(long date)
常用方法
getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
toString():把此 Date 对象转换为以下形式的 String: dow mon ddhh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat),zzz是时间标准。
public void Test2(){
//构造器一(空参构造器):Date(),创建一个对应当前时间的Date
Date date=new Date();
System.out.println(date.toString());//显示当前年月日时分秒
System.out.println(date.getTime());//输出的是毫秒数。也是时间戳
//构造器二:创建指定毫秒数的对象,转换成具体的时间对象
Date date1 = new Date(1595901307554L);
System.out.println(date1.toString());
}
关机Date()类,会归属在两个包底下:Util和sql。
关于在sql包底下,在数据库的章节会具体讲解
sql.Date()–>util.Date()对象?直接去赋值(多态的性质)
@Test
public void Test3(){
//如何将java.util.Date对象转化成java.sql.Date
//情况一:
Date date1=new java.sql.Date(15689798798L);
java.sql.Date date2=(java.sql.Date) date1;//不会出错
System.out.println(date2.toString());
//注意多态,new出的父类,你强转成子类是不可行的
//情况二:
Date date3=new Date();
//把date3的毫秒数拿来,作为sql.Date()的参数
java.sql.Date date4=new java.sql.Date(date3.getTime());
System.out.println(date4.toString());
}
3. java.text.SimpleDateFormat类 (简单的日期格式化)
Date类的API不易于国际化,大部分被废弃了,java.text.SimpleDateFormat
类是一个不与语言环境有关的方式来格式化和解析日期的具体类。
·它允许进行格式化:日期–>文本、解析:文本–>日期
· 格式化:
SimpleDateFormat() :默认的模式和语言环境创建对象
public SimpleDateFormat(String pattern):该构造方法可以用参数pattern
指定的格式创建一个对象,该对象调用:
public String format(Date date):方法格式化时间对象date
解析:
public Date parse(String source):从给定字符串的开始解析文本,以生成一个日期。
1.两个操作
(1)格式化:日期--->指定格式的字符串
(2)解析:格式化的逆过程,字符串--->日期
*/
@Test
public void Test1() throws ParseException {
SimpleDateFormat sdf=new SimpleDateFormat();
//
Date date=new Date();
System.out.println(date);
String format=sdf.format(date);
System.out.println(format);
//如何去指定日期的格式呢?
String str="19-21-18 上午11:45";
Date date1 = sdf.parse(format);
//***************
//年:y
//月:M
//日:d
//时:h
//分:m
//秒:s
//一般使用带参的构造器
//SimpleDateFormat只不过是帮我去进行格式化的一个工具
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd kk-mm-ss");
//格式化:古里古怪的数字,转成我们想要看到的格式
String format1 = sdf1.format(date);
System.out.println(format1);
//解析:要求 我们的字符串必须符合SimpleDateFormat的形参要求
//否则会抛出异常
Date date2 = sdf1.parse("2020-07-28 23-35-49");
System.out.println(date2);
}
输出结果:
这里引入一个练习题:
练习一:字符串"2020-09-08转换成Date(java.sql.Date)
/*
练习一:字符串"2020-09-08转换成Date(java.sql.Date)"
*/
@Test
public void TestExercise() throws ParseException {
//其实这就是一个解析的过程,从具体的日期-->古里古怪的日期
String str ="2020-09-08";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(str);
System.out.println(date);
//现在需要去进行类型转换,从util的date转化为sql的date
java.sql.Date birthDate=new java.sql.Date(date.getTime());
System.out.println(birthDate);
}
(4) java.util.Calendar(日历)类 :
Calendar是一个抽象基类,主用用于完成日期字段之间相互操作的功能。
获取Calendar实例的方法
使用Calendar.getInstance()方法
调用它的子类GregorianCalendar的构造器。
一个Calendar的实例是系统时间的抽象表示,通过get(int field)方法来取得想要的时间信息。比如YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、 MINUTE、SECOND
public void set(int field,int value)
public void add(int field,int amount)
public final Date getTime()
public final void setTime(Date date)
注意:
获取月份时:一月是0,二月是1,以此类推,12月是11
获取星期时:周日是1,周二是2 , 。。。。周六是7
Calendar的部分源代码,注意这是一个抽象类abstract,无法去new,也就是说无法去实例化,所以要使用子类去创建对象。
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
Calendar使用及其代码如下:
/**
* calendar日历类的使用
*/
@Test
public void TestCalendar(){
//1.实例化
//方式一:创建其子类(GregorianCalendar)的对象
//方式二:调用其静态方法getInstance()
Calendar calendar = Calendar.getInstance();//其实这个方法还是子类创造的
//System.out.println(calendar.getClass());
//常用方法:
//get()---->参数int field
//可以获得这个月的一些数据,比如一年的第几个月,一个月的第几天
int days = calendar.get(calendar.DAY_OF_MONTH);
int weeks = calendar.get(calendar.WEEK_OF_MONTH);
System.out.println("这个月的第 : "+days+"天");
System.out.println("这个月的第 : "+weeks+"周");
//set():将某些属性设置为新的值。返回值是void
calendar.set(calendar.DAY_OF_MONTH,26);
days = calendar.get(calendar.DAY_OF_MONTH);
System.out.println("新设置后,这是这个月的第 : "+days+"天");
//add():在原有的对象上进行添加(比如添加天数)。返回值是void
calendar.add(calendar.DAY_OF_MONTH,2);
days = calendar.get(calendar.DAY_OF_MONTH);
System.out.println("新设置后,这是这个月的第 : "+days+"天");
//getTime:Calendar与date之间的转换
Date date = calendar.getTime();
System.out.println(date);
// setTime():Date--->日历类
Date date1 = new Date();
calendar.setTime(date1);
days = calendar.get(calendar.DAY_OF_MONTH);
System.out.println("这是这个月的第 : "+days+"天");
}
执行结果如下: