目录
一、内部类
1.1 内部类的分类
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
1.2 什么是内部类
概念:在一个类的内部再定义一个完整的类。
特点:
- 编译之后可生成独立的字节码文件。 .class文件
- 内部类可直接访问外部类的私有成员,而不破坏封装。
- 可为外部类提供必要的内部功能组件。
1.3 成员内部类
- 在类的内部定义,与实例变量、实例方法同级别的类。
- 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。
Outer out = new Outer();
Outer.Inner in = out.new Inner();- 当外部类、内部类存在重名属性时,会优先访问内部类属性。
- 成员内部类不能定义静态成员。
案例演示:成员内部类使用。
package com.qfedu;
/**
* 内部类
* : 成员内部类 静态内部类 局部内部类 匿名内部类
*
* :成员内部类: 1.类内部 与 属性和方法平级
* 2. .class 独立生成 Test1$InnerClass.class: javac去测试
* 3.创建格式: //Outer out = new Outer();
* //Outer.Inner in = out.new Inner();
* 4. 外部类的私有属性: 可以被成员内部类访问!
*/
public class Test1Outer {
int a = 1;
private int b = 1;
public void add() {
System.out.println(a);
System.out.println("add");
}
//成员内部类
class InnerClass{
private int a = 2;
public void delete() {
System.out.println(a);
System.out.println(b);
System.out.println("delete");
}
}
}
package com.qfedu;
public class Test2Outer {
public static void main(String[] args) {
//Outer out = new Outer();
//Outer.Inner in = out.new Inner();
//1.仿造上面格式创建外部类对象
Test1Outer test1 = new Test1Outer();
Test1Outer.InnerClass innerClass= test1.new InnerClass();
innerClass.delete();
}
}
注:打印外部类的属性,内部类属性和外部类的属性名字相同Outer.this。
1.4 静态内部类
- 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员。
- 只能直接访问外部类的静态成员(实例成员需实例化外部类对象)。
Outer.Inner inner = new Outer.Inner();
Outer.Inner.show();
案例演示:静态内部类使用。
package com.qfedu;
//静态内部类
public class Test3StaticOuter {
private int a = 1;
public void add() {
}
static class InnerClss {
private int b = 2;
public void delete() {
}
}
}
public class Test4StaticOuter {
public static void main(String[] args) {
// 定义静态内部类
Test3StaticOuter.InnerClss innerClss = new Test3StaticOuter.InnerClss();
}
}
1.5 局部内部类
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法。
也就是说:只能在方法中new 对象
局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,
也就是说: 局部内中使用方法的 变量 ,生成的class文件会在变量前自动添加 final
限制类的使用范围.
也就是只能在方法内部使用。
案例演示:局部内部类使用。
package com.qfedu;
public interface A {
void delete();
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.qfedu;
public class Test5Outer {
int a = 1;
public Test5Outer() {
}
public A add() {
final int a = 1;
class InnerClass implements A {
InnerClass() {
}
public void delete() {
System.out.println(a);
}
}
InnerClass innerClass = new InnerClass();
return innerClass;
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.qfedu;
public class Test6Outer {
public Test6Outer() {
}
public static void main(String[] args) {
Test5Outer test5Outer = new Test5Outer();
A innerClass = test5Outer.add();
innerClass.delete();
}
}
1.6 匿名内部类(重点)
- 没有类名的局部内部类(一切特征都与局部内部类相同)。
- 必须继承一个父类或者实现一个接口。
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象。
- 优点:减少代码量。
- 缺点:可读性较差。
案例演示:匿名内部类使用。
//匿名内部类:
//1.有接口没有实现类: 如果有: 创建对象的方式:多态
public interface Test7Interface {
boolean add();
void delete();
}
//匿名内部类的创建
public class Test8 {
public static void main(String[] args) {
// 接口 对象名 = new 实现类(); 在实现类里add()重写方法 对象名.add();
//1.只有接口,没有实现类
//2.匿名内部类:
//接口类名 对象名 = new 接口类名(){
// 重写方法
// }
//3.返回值 是一个实例对象
//3.最后加; 表示结束
Test7Interface test7Interface = new Test7Interface() {
@Override
public boolean add() {
return false;
}
@Override
public void delete() {
System.out.println("重写里边的内容");
}
};
boolean add = test7Interface.add();
}
}
二、Object类【重点】
2.1 概述
- 超类、基类,所有类的直接或间接父类,位于继承树的最顶层。
- 任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承。
- Object类中所定义的方法,是所有对象都具备的方法。
- Object类型可以存储任何对象。
- 作为参数,可接受任何对象。
- 作为返回值,可返回任何对象。
2.2 常用方法
2.2.1 getClass() (重点)
public final Class<?> getClass(){…}
- 返回引用中存储的实际对象类型。
- 应用:通常用于判断两个引用中实际存储对象类型是否一致。
实体类:
package com.qfedu.homework;
public class Hero {
public Integer a ;
public String b;
//属性id
private Integer id;
//属性namea
private String name;
//构造器
public Hero() {
}
//有参构造器
public Hero(Integer id, String name) {
this.id = id;
this.name = name;
}
private Hero(Integer a, String b, Integer id, String name) {
this.a = a;
this.b = b;
this.id = id;
this.name = name;
}
// 其余方法
//新增方法
public boolean add() {
System.out.println("我add");
return true;
}
//删除方法
private void delete(Integer id) {
System.out.println("我删了你。。。");
}
}
package com.qfedu.homework;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class HeroTest {
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InstantiationException {
//1.创建对象 获取Hero 对应的class对应
/*Hero hero = new Hero();
Class heroClass = hero.getClass();*/
Class heroClass = Class.forName("com.qfedu.homework.Hero");
//1.获取类名
System.out.println(heroClass.getName());
//获取包名
System.out.println(heroClass.getPackage());
//属性。。。。。。。。。。。。。。。。。。。。。。
//获取 public 的属性 getFields()
System.out.println("==============public 类型 的 属性==================");
Field[] fields = heroClass.getFields();
for (Field field : fields) {
System.out.println(field.getName());
}
System.out.println("==============public 类型 的 单个属性==================");
//获取public 属性getField(String name) //name 指的是属性名
Field b = heroClass.getField("b");
System.out.println("属性类型:"+b.getType().getName());
System.out.println("属性名:"+b.getName());
System.out.println("=============所有属性==================");
//获取所有属性,不包括继承getDeclaredFields() Declared 已声明 的
Field[] declaredFields = heroClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getName());
}
System.out.println("=============所有中的单个属性==================");
//获取任意属性:getDeclaredField(String name)
Field id = heroClass.getDeclaredField("id");
System.out.println(id.getName());
//构造器。。。。。。。。。。。。。。。。。。。。。Constructor
System.out.println("==============public 类型 的 构造器==================");
//获取public构造器 数组,用来显示,数组参数getConstructors()
Constructor[] constructors = heroClass.getConstructors();
for (Constructor constructor : constructors) { // parameter 参数的意思
System.out.println(constructor.getParameterCount()); //参数的个数
}
System.out.println("==============public 类型 的 单个 构造器==================");
Constructor constructor = heroClass.getConstructor(null);
System.out.println(constructor.getParameterCount());
Constructor constructor1 = heroClass.getConstructor(Integer.class, String.class);
System.out.println(constructor1.getParameterCount());
System.out.println("==============所有的 构造器==================");
//获取所有的构造方法getDeclaredConstructors();
Constructor[] declaredConstructors = heroClass.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor.getParameterCount());
}
//方法。。。。。。。。。。。。
System.out.println("==============所有的 public 方法 ==================");
//获取public 的方法 getMethods() 以及所有的继承方法
Method[] methods = heroClass.getMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
System.out.println("==============所有的 public 单个方法 ==================");
//获取public 的方法 getMethods(String name,Class[] params) //指定方法的名称和参数列表
Method add = heroClass.getMethod("add", null);
System.out.println(add.getReturnType().getName());
System.out.println("==============所有的 已声明 的 方法 ==================");
//获取所有方法 getDeclaredMethods()
Method[] declaredMethods = heroClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getName());
}
System.out.println("==============所有的 已声明 的 单个 方法 ==================");
//获取单个方法getDeclaredMethods(String name,Class[] params)
Method delete = heroClass.getDeclaredMethod("delete", Integer.class);
System.out.println(delete.getName());
//自己创建对象
Hero hero = new Hero();
hero.add();
Object o1 = new Hero();
//通过newInstance() 通过这个方法new 一个对象,无参构造器
Object o = heroClass.newInstance();
Hero hero1 = (Hero)o;
hero1.add();
}
}
2.2.2 hashCode()方法
- 返回该对象的十进制的哈希码值。
- 哈希算法根据对象的地址或字符串或数字计算出来的int类型的数值。
- 哈希码并不唯一,可保证相同对象返回相同哈希码,尽量保证不同对象返回不同哈希码。
package com.qfedu.test03;
public class Test01 {
public static void main(String[] args) {
Test01 t1 = new Test01();
System.out.println(t1.hashCode());
Test01 t2 = new Test01();
System.out.println(t2.hashCode());
Test01 t3 = t1;
// 比较提 地址 ==
System.out.println(t3==t1);
System.out.println(t3.hashCode() ==t1.hashCode());
}
}
2.2.3 toString()方法
- 返回该对象的字符串表示(表现形式)。
- 可以根据程序需求覆盖该方法,如:展示对象各个属性值。
2.2.4 equals()方法
public boolean equals(Object obj){…}
- 默认实现为(this == obj),比较两个对象地址是否相同。
- 可进行覆盖,比较两个对象的内容是否相同。
equals重写步骤:
- 比较两个引用是否指向同一个对象。
- 判断obj是否为null。
- 判断两个引用指向的实际对象类型是否一致。
- 强制类型转换。
- 依次比较各个属性值是否相同。
package com.qfedu.test03;
//1. 在字符串里 比的是 值
public class Test02 {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
//2.可以利用equlas 自定义比较规则
public static void main(String[] args) {
//1.创建第一个对象
Test02 t1 = new Test02();
t1.setName("小乔");
Test02 t2 = new Test02();
t2.setName("小乔");
boolean equals = t1.equals(t2);
System.out.println(equals);
}
// 对象1.equals(对象2)
// 判断 对象1 是不是和对象2 相同
// 1.地址 相同相同 内容相同也相同
public boolean equals(Object obj) {
//1. 如果地址 相嶁 ,那么相同
if(this== obj) {
return true;
}else {
//2判断是否是再跟一个对象
if(obj instanceof Test02) {
//3. 如果地址 不同: 判断name 内容是否相同,如果相同是一个对象
//对象1的name
String name1 = this.getName();
//对象2的name
Test02 t2 = (Test02)obj;
String name2 = t2.getName();
if(name1.equals(name2)) {
return true;
}else {
return false;
}
}else {
return false;
}
}
}
}
2.2.5 finalize()方法
- 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列。
- 垃圾对象:没有有效引用指向此对象时,为垃圾对象。
- 垃圾回收: 由GC销毁垃圾对象,释放数据存储空间。
- 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象。
- 手动回收机制:使用System.gc(); 通知JVM执行垃圾回收。
引用:
强引用: 一般new 出来,只要引用还存在,就不会被回收!
软引用: 回收没有被引用的对象, 还不够,回收那些有指向的引用: 标记: SoftReference
弱引用 : 如果内存不够,回收! 比软引用还弱:标记: WeakReference
虚引用: 指的回收的时候的通知!:标记:PhantomReference
public class TestFinalize {
public static void main(String[] args) {
// Student s1=new Student("aaa", 20);
// Student s2=new Student("bbb", 20);
// Student s3=new Student("ccc", 20);
// Student s4=new Student("ddd", 20);
Student s5=new Student("eee", 20);
s5 = null;
new Student("aaa", 20);
new Student("bbb", 20);
new Student("ccc", 20);
new Student("ddd", 20);
new Student("eee", 20);
//回收垃圾
System.gc();
System.out.println("回收垃圾");
}
}
三、包装类
3.1 概述
- 基本数据类型所对应的引用数据类型。
- Object可统一所有数据,包装类的默认值是null。
基本类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
3.2 装箱、拆箱
- 八种包装类提供不同类型间的转换方式。
- Number父类中提供的6个共性方法。
- parseXXX()静态方法(除了Character)。
- valueOf()静态方法。
- 注意:需保证类型兼容,否则抛出NumberFormatException异常。
- JDK 5.0之后,自动装箱、拆箱。基本数据类型和包装类自动转换。
案例演示:包装类使用。
package com.qfedu;
//基本类型的包装类
public class Test13 {
public static void main(String[] args) {
//1. int == 》 Integer 定义
Integer id = 1;
Integer integer = new Integer("1");
Integer integer1 = new Integer(2);
System.out.println(integer);
//访问类中的方法 把String ==> int
int i = Integer.parseInt("2");
Integer integer2 = Integer.valueOf("3");
// byte short long float double
//byte
byte b = 1;
Byte byte1 = new Byte(b);
Byte byte2 = new Byte("2");
// String ==>byte
byte b1 = Byte.parseByte("3");
Byte aByte = Byte.valueOf("4");
//
short s = 3;
Short short1 = new Short(s);
Short short2 = new Short("4");
short i1 = Short.parseShort("5");
Short aShort = Short.valueOf("4");
//long
long l1 = 1L;
Long long1 = new Long(l1);
Long long2 = new Long("5");
long l = Long.parseLong("5");
Long aLong = Long.valueOf("444");
//float
float f = 1.0F;
Float f1 = new Float(f);
Float aFloat = new Float(0.9);
Float aFloat1 = new Float("4");
float v = Float.parseFloat("44");
Float aFloat2 = Float.valueOf("44");
//double
Double double0 = 0.1;
Double double1 = new Double(1.0);
Double double2 = new Double("2.1");
double v1 = Double.parseDouble("4.5");
Double aDouble = Double.valueOf("4.5");
Boolean boolean1 = new Boolean("true");
boolean b2 = boolean1.booleanValue();
System.out.println(b2);
boolean aFalse = Boolean.parseBoolean("false");
Boolean aBoolean = Boolean.valueOf(false);
char c = 'A';
Character character1 = new Character(c);
Character character = Character.valueOf(c);
}
}
package com.qfedu.test06;
//基本类型 ==》 引用类型
public class Test01 {
public static void main(String[] args) {
int i = 300;
//1 基本类型转成 对应的 引用类型
//1.1 用new的方式 int Integer
Integer a = new Integer(300);
//1.2 调用对象类的静态方法 int ==> integer
Integer integer = Integer.valueOf("500");
//2. 引用类型==》基本类型
//2.1 对象的普通 方法
int i1 = a.intValue();
//2.2
int i2 = Integer.parseInt("400");
System.out.println(i2);
//2.byte
// byte ==> Byte
byte b = 127;
Byte byte1 = new Byte(b);
Byte aByte = Byte.valueOf(b);
// Byte ==> byte
byte b1 = Byte.parseByte(b + "");
//3.short
short s = 300;
Short s1 = new Short(s);
Short aShort = Short.valueOf(s);
// Short ==> short
short i3 = Short.parseShort(s + "");
System.out.println(i3);
//4. long
long aa = 500L;
Long al = new Long(aa);
Long aLong = Long.valueOf(aa);
long l = Long.parseLong(al + "");
//5. double
double d = 1.1;
Double d1 = new Double(d);
Double aDouble = Double.valueOf(d);
double v = Double.parseDouble(aDouble + "");
//6char
char c = 'a';
Character c1 = new Character(c);
Character character = c;
char c2 = character.charValue();
System.out.println(c2);
String str1 = "800";
//接收参数转成字符串
String s2 = String.valueOf(400);
}
}
3.3 整数缓冲区
Java预先创建了256个常用的整数包装类型对象。(-128~127)的常数)在实际应用当中,对已创建的对象进行复用,节约内存效果明显。
面试题:分析以下输出结果的原因。
public class TestInteger2 {
public static void main(String[] args) {
//面试题
Integer integer1=new Integer(100);
Integer integer2=new Integer(100);
System.out.println(integer1==integer2);
Integer integer3=Integer.valueOf(100);//自动装箱Integer.valueOf
Integer integer4=Integer.valueOf(100);
System.out.println(integer3==integer4);//true
Integer integer5=Integer.valueOf(200);//自动装箱
Integer integer6=Integer.valueOf(200);
System.out.println(integer5==integer6);//false
}
}
四、String类【重点】
4.1 概述
- Java程序中的所有字符串文本(例如“abc”)都是此类的实例。
- 字符串字面值是常量,创建之后不可改变。
- 常用创建方式:
- String str1 = “Hello”;
- String str2 = new String(“World”);
4.2 常用方法
方法名 | 描述 |
---|---|
public char charAt(int index) | 根据下标获取字符 |
public boolean contains(String str) | 判断当前字符串中是否包含str |
public char[] toCharArray() | 将字符串转换成数组。 |
public int indexOf(String str) | 查找str首次出现的下标,存在,则返回该下标;不存在,则返回-1 |
public int length() | 返回字符串的长度 |
public String trim() | 去掉字符串前后的空格 |
public String toUpperCase() | 将小写转成大写 |
public boolean endsWith(String str) | 判断字符串是否以str结尾 |
public String replace(char oldChar,char newChar) | 将旧字符串替换成新字符串 |
public String[] split(String str) | 根据str做拆分 |
public String subString(int beginIndex,int endIndex) | 在字符串中截取出一个子字符串 |
案例演示:String的使用。
package com.qfedu.test03;
import java.util.Arrays;
//字符串的方法
public class Test04 {
public static void main(String[] args) {
//1.定义一个字符串
String str = "abcadef123563abceiafaesf;abcweifa";
//*1.根据下标获取字符: 下标从0开始,下标传入的范围 0- len-1
char c = str.charAt(0);
System.out.println(c);
System.out.println("====**数组长度");
//2.字符串的长度 : 是一个方法,
int length = str.length();
System.out.println("length="+length);
//数组的长度是一个属性
int[] a = new int[2];
System.out.println(""+a.length);
System.out.println("=============*转数组");
//3.将字符串,转成数组
char[] chars = str.toCharArray();
//参数1: 来源数组 2:来源数组下标 3: 目标数组 4目标数组开始下标 5 复制的个数
//System.arraycopy(value, 0, result, 0, value.length);
System.out.println(Arrays.toString(chars));
System.out.println("=====*查找str首次出现的下标,存在,则返回该下标;不存在,则返回-1");
int abc = str.indexOf("abc");
System.out.println(abc);
System.out.println("==========**截取字符串,返回一个新的字符串,原字符串不变");
String str2 = "abcdefg123abc";
String substring = str2.substring(1);
System.out.println("从指定下标开始截取 :"+substring);
String substring1 = str2.substring(1, 3);
System.out.println("开始下标和结束下标"+substring1);
System.out.println("str2"+str2);
System.out.println("====*去掉两边的空格======");
String str1 = " a b c ";
//会返回新的字符串
String trim = str1.trim();
System.out.println("str1="+str1);
System.out.println("trim="+trim);
System.out.println("==============*转大小写=======================");
String str4 = "abcDEfg";
String s1 = str4.toUpperCase();
String s2 = str4.toLowerCase();
System.out.println(s1);
System.out.println(s2);
System.out.println(str4);
System.out.println("=======**是否以某个字符串开头或结尾=====");
boolean abc1 = str4.startsWith("abc");
boolean gg = str4.endsWith("gg");
System.out.println(abc1);
System.out.println(gg);
System.out.println("=========**替换");
String str5 = "abcD Efg";
String replace = str5.replace(" ", "jQK");
System.out.println(replace);
System.out.println(str5);
System.out.println("======**切割====");
String ids= "大乔,小乔,小乔他爸";
String[] split = ids.split(",");
System.out.println(split.length);
System.out.println("判断是否包含");
boolean b = ids.contains("小乔");
System.out.println(b);
System.out.println("==比较少用:连接字符串");
String str6 = "aaa";
String concat = str6.concat(ids);
System.out.println(concat);
}
}
五、可变字符串
5.1概念
可在内存中创建可变的缓冲空间,存储频繁改变的字符串。
- Java中提供了两个可变字符串类:
- StringBuilder:可变长字符串,JDK5.0提供,运行效率快、线程不安全。
- StringBuffer:可变长字符串,JDK1.0提供,运行效率慢、线程安全。
- 这两个类中方法和属性完全一致。
5.2常用方法
方法名 | 属性 |
---|---|
public StringBuilder append(String str) | 追加内容。 |
public StringBuilder insert(int dstOffset, CharSequence s) | 将指定 字符串插入此序列中。 |
public StringBuilder delete(int start, int end) | 移除此序列的子字符串中的字符。 |
public StringBuilder replace(int start, int end, String str) | 使用给定字符串替换此序列的子字符串中的字符。start开始位置、end结束位置。 |
public int length() | 返回长度(字符数)。 |
案例演示:StringBuilder的使用。
package com.qfedu.test03;
//StringBuider 可变字符串
public class Test05 {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("abc");
System.out.println(sb);
//1添加字字符串
sb.append("ef");
System.out.println(sb.toString());
System.out.println(sb.hashCode());
System.out.println("插入=====");
sb.insert(1,"jQK");
System.out.println(sb);
System.out.println("删除=======,结束(end-1)");
System.out.println(sb);
sb.delete(0,11111);
System.out.println(sb);
sb.append("45rtuy");
//sb = null;
System.out.println("替换==========");
System.out.println(sb);
sb.replace(3,6,"GGGGGGGGGGGGGGGGGGGG");
System.out.println(sb);
System.out.println(sb.length());
//StringBuffer
StringBuffer buf = new StringBuffer("aaa");
buf.append("eee");
buf.insert(1,"ffff");
buf.delete(0,1);
buf.replace(0,1,"555");
System.out.println(buf);
}
}
案例演示:验证StringBuilder效率高于String。
public class TestStringBuilder2 {
public static void main(String[] args) {
//测试执行的毫秒数
//1.当前时间 用毫秒数表示
long start = System.currentTimeMillis();
StringBuilder sb1 = new StringBuilder("");
StringBuffer sb2 = new StringBuffer("");
//2.中间代码
for (int i = 0; i < 99999; i++) {
sb2.append(i);
}
//2.结束时间
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
六、BigDecimal
6.1 为什么使用BigDecimal
6.2 BigDeicmal基本用法
- 位置:java.math包中。
- 作用:精确计算浮点数。
- 创建方式:BigDecimal bd=new BigDecimal(“1.0”)。
常用方法:
方法名 | 描述 |
---|---|
BigDecimal add(BigDecimal bd) | 加 |
BigDecimal subtract(BigDecimal bd) | 减 |
BigDecimal multiply(BigDecimal bd) | 乘 |
BigDecimal divide(BigDecimal bd) | 除 |
- 除法:divide(BigDecimal bd,int scal,RoundingMode mode)。
- 参数scale :指定精确到小数点后几位。
- 参数mode :
- 指定小数部分的取舍模式,通常采用四舍五入的模式。
- 取值为BigDecimal.ROUND_HALF_UP。
package com.qfedu.test05;
import java.math.BigDecimal;
//BigDeicmal
//用来做小数的精确计算:
public class Test01 {
public static void main(String[] args) {
double d1 = 1.0;
double d2 = 0.9;
System.out.println(d1-d2);
//1.为啥它不准
//2进制
double d = 10.1;
//存储 ==》 二进制
//整数部分10 ==>1010
// 小数部分==》 小数部分 *2 取整
//0.1 * 2 = 0.2 ==>0
//0.2 *2 ==0.4 ==>0
//0.4 *2 == 0.8 0
//0.8*2 == 1.6 1
//0.6*2 == 1.2 1
//0.2 *2 ==0.4 ==>0
//0.4 *2 == 0.8 0
//0.8*2 == 1.6 1
//0.6*2 == 1.2 1
//0.2 *2 ==0.4 ==>0
//0.4 *2 == 0.8 0
//0.8*2 == 1.6 1
//0.6*2 == 1.2 1
// 1010.0001100110011001........
// 1. 转成BigDeicmal
BigDecimal b1 = new BigDecimal("1.0");
BigDecimal b2 = new BigDecimal("0.9");
//2. 进行加减乘除
BigDecimal add = b1.add(b2);
System.out.println(add);
BigDecimal subtract = b1.subtract(b2);
System.out.println(subtract);
BigDecimal multiply = b1.multiply(b2);
System.out.println(multiply);
// 小数保留 参数2:小数的位数 参数3: 保留策略
BigDecimal divide = b1.divide(b2,3,BigDecimal.ROUND_HALF_UP);
System.out.println(divide);
}
}
七、Date
Date表示特定的瞬间,精确到毫秒。
Date类中的大部分方法都已经被Calendar类中的方法所取代。
时间单位
- 1秒=1000毫秒
- 1毫秒=1000微秒
- 1微秒=1000纳秒
1秒= 1000000000纳秒
时间轮片
案例演示:
package com.qfedu;
import java.util.Date;
public class Test4 {
//1.属性上会用 创建日期 生日 下单时间 支付时间 java.util.Date
private Date hireDate;
private Date birthDate;
private Date createTime;
private Date orderTime;
private Date payTime;
public static void main(String[] args) {
//1.new Date() 指的是当前时间
Date date = new Date();
System.out.println(date);
System.out.println(date.toString());
System.out.println(date.toLocaleString()); //local 本地
//获取当前时间的毫秒数
long time = date.getTime();
System.out.println(time);
//计算昨天
Date date2=new Date(date.getTime()-(24*60*60*1000));
System.out.println(date2.toLocaleString());
//比较两个日期
boolean before = date.before(date2);
System.out.println(before);
boolean after = date.after(date2);
System.out.println(after);
//比较 compareTo(); date> date2 : 1 date<date2:-1 date==date2 :0
int d=date2.compareTo(date2);
System.out.println(d);
//比较是否相等 equals()
boolean b3=date.equals(date2);
System.out.println(b3);
System.out.println(
(date.getYear()+1900)+"年"+
date.getMonth()+"月"+
date.getDay()+"日"
)
}
}
八、Calendar
- Calendar提供了获取或设置各种日历字段的方法。
- protected Calendar() 构造方法为protected修饰,无法直接创建该对象。
常用方法:
方法名 | 说明 |
---|---|
static Calendar getInstance() | 使用默认时区和区域获取日历 |
int get(int field) | 返回给定日历字段的值。字段比如年、月、日等,field用静态属性 |
void setTime(Date date) | 用给定的Date设置此日历的时间。Date-Calendar |
Date getTime() | 返回一个Date表示此日历的时间。Calendar-Date |
void add(int field,int amount) | 按照日历的规则,给指定字段添加或减少时间量field 可以用静态属性 |
long getTimeInMillis() | 毫秒为单位返回该日历的时间值 |
案例演示:
package com.qfedu;
import java.util.Calendar;
import java.util.Date;
public class Test5 {
public static void main(String[] args) {
//获取方式
Calendar instance = Calendar.getInstance();
Date time = instance.getTime();
System.out.println(time.toLocaleString());
//instance.set(0,0,0,0,0,0);
System.out.println(instance.get(Calendar.YEAR));// 年
System.out.println(instance.get(Calendar.MONTH)); //月
System.out.println(instance.get(Calendar.DAY_OF_MONTH)); // 返回本月多少天
System.out.println(instance.get(Calendar.DATE));//日
System.out.println(instance.get(Calendar.WEEK_OF_MONTH));
//今天是星期几
System.out.println(instance.get(Calendar.DAY_OF_WEEK));
System.out.println(instance.get(Calendar.HOUR));
System.out.println(instance.get(Calendar.MINUTE));
System.out.println(instance.get(Calendar.SECOND));
//设置日期
instance.setTime(new Date());
//返回毫秒数
long timeInMillis = instance.getTimeInMillis();
//1天以后
instance.add(Calendar.WEDNESDAY,0);
System.out.println(instance.getTime().toLocaleString());
}
}
九、SimpleDateFormat(*)
- SimpleDateFormat是以与语言环境有关的方式来格式化和解析日期的类。
- 进行格式化(日期 -> 文本)、解析(文本 -> 日期)。
常用时间模式字母:
字母 | 日期或时间 | 示例 |
---|---|---|
y | 年 | 2019 |
M | 年中月份 | 08 |
d | 月中天数 | 10 |
H | 1天中小时数(0-23) | 22 |
m | 分钟 | 16 |
s | 秒 | 59 |
S | 毫秒 | 367 |
案例演示:
//1.指定输出格式 yyyy-MM-dd HH:mm:ss
Date date =new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
//2.把日期按照格式==》字符串
String format = sdf.format(date);
System.out.println(format);
// 字符串
String dateStr = "2021/06/30 16:53:29";
Date parse = sdf.parse(dateStr);
System.out.println(parse.toLocaleString());
十、System
System系统类,主要用于获取系统的属性数据和其他操作。
常用方法:
方法名 | 说明 |
---|---|
static void arraycopy(…) | 复制数组 |
static long currentTimeMillis() | 获取当前系统时间,返回的是毫秒值 |
static void gc(); | 建议JVM赶快启动垃圾回收器回收垃圾 |
static void exit(int status) | 退出jvm,如果参数是0表示正常退出jvm,非0表示异常退出jvm。 |
案例演示:
package com.qfedu;
public class Test6 {
public static void main(String[] args) {
//毫秒数
long startTime = System.currentTimeMillis();
//执行代码
for(int i=0; i<100; i++) {
System.out.println(i);
}
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime);
System.gc(); //回收
System.exit(0); //退出jvm
}
}