Object
Object类概述
- Object类——超类、基类,所有类的直接或间接父类(所有类都直接或间接继承Object类),位于继承树的最顶层。
- 任何类,如果没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承。
- Object类中所定义的方法,是所有对象都具备的方法。
- Object类型可以存储任何对象。
- 作为参数,可接受任何对象。
- 作为返回值,可返回任何对象。
getClass()
-
public final Class<?> getClass(){}
-
返回引用中存储的实际对象类型
-
应用:通常用于判断两个引用中实际存储对象类型是否一致。
实例
class Start{
public static void main(String[] args) {
Student wang =new Student("王刚",13);
Student ming = new Student("王明", 16);
Class c1 = wang.getClass();
Class c2 = ming.getClass();
if (c1==c2){
System.out.println(true);
}else{
System.out.println(false);
}
}
}
public class Student{
private String name;
private int age;
public Student(){}
public Student(String name, int age) {
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;
}
}
运行结果:
true
hashCode()
-
public int hashCode(){}
-
返回该对象的哈希码值
-
哈希值根据对象的地址或字符串或数字使用hash算法计算出来的int类型的数值。
-
一般情况下相同对象返回相同哈希码。
class Start{
public static void main(String[] args) {
Student s1 = new Student("王刚",13);
Student s2 = new Student("王明", 16);
Student s3 = s1;
int i1 = s1.hashCode();
int i2 = s2.hashCode();
int i3 = s1;
System.out.println(i1==i2);//false
System.out.println(i1==i3);//true
System.out.println(i2==i3);//false
}
}
public class Student{
private String name;
private int age;
public Student(){}
public Student(String name, int age) {
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;
}
}
toString()
-
public String toString(){}
-
返回该对象的字符串表示(表现形式)
-
可以根据程序需求覆盖该方法,如:展示对象各个属性值
//继续沿用上面的代码
class Start{
public static void main(String[] args) {
Student s1 = new Student("王刚",13);
System.out.println(s1.toString);
}
}
public class Student{
private String name;
private int age;
public Student(){}
public Student(String name, int age) {
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;
}
}
运行结果:
包名.类名@哈希值
//这里的哈希值是十六进制
这肯定不是我们想要的,所以我们此时重写toString()方法
//继续沿用上面的代码
class Start{
public static void main(String[] args) {
Student s1 = new Student("王刚",13);
System.out.println(s1.toString);
}
}
public class Student{
private String name;
private int age;
public Student(){}
public Student(String name, int age) {
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 String toString(){
return "姓名:"+name+" 年龄:"+age;
}
}
此时,运行结果为:
姓名:王刚 年龄:13
equals()
-
public boolean equals(Object obj){}
-
默认实现伪(this == obj),比较两个对象地址是否相同。
-
可进行覆盖,比较两个对象的内容是否相同。
//继续沿用上面的代码
class Start{
public static void main(String[] args) {
Student s1 = new Student("王刚",13);
Student s2 = new Student("王刚",13);
System.out.println(s1.equals(s2));
}
}
public class Student{
private String name;
private int age;
public Student(){}
public Student(String name, int age) {
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 String toString(){
return "姓名:"+name+" 年龄:"+age;
}
}
运行结果:
false
但是,这可能不是我们想要的,我们可能想要比较name和age,此时,我们就要重写equals()方法。
//继续沿用上面的代码
class Start{
public static void main(String[] args) {
Student s1 = new Student("王刚",13);
Student s2 = new Student("王刚",13);
System.out.println(s1.equals(s2));
}
}
public class Student{
private String name;
private int age;
public Student(){}
public Student(String name, int age) {
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 String toString(){
return "姓名:"+name+" 年龄:"+age;
}
@Override
public boolean equals(Object obj){
//比较两个引用是否指向同一个对象
if(this == obj){
return true;
}
//判断obj是否为null
if(obj == null){
return false;
}
//判断两个引用指向的实际对象类型是否一致
if(obj instanceof Student){
//强制类型转换
Student s =(Student)obj;
//依次比较各个属性值是否相同
if(this.name.equals(s.getName()) && this.age == s.getAge){
return turn;
}
}
}
}
此时的运行结果:
true
finalize()
- 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列。
- 垃圾对象:没有有效引用此对象时,为垃圾对象。
- 垃圾回收:由GC销毁垃圾对象,释放数据存储空间。
- 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象。
- 手动回收机制:使用System.gc();通知JVM执行垃圾回收。
class Application {
public static void main(String[] args) {
new Student("小刚",16);
new Student("小王",13);
new Student("小花",19);
new Student("小丽",15);
System.gc();
}
}
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
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
protected void finalize() throws Throwable {
super.finalize();
System.out.println(this.getName()+"被回收了!!!");
//为了显示出来,所以在这里重写finalize方法,告诉我们那个对象被回收了。
}
}
运行结果:
小丽被回收了!!!
小花被回收了!!!
小王被回收了!!!
小刚被回收了!!!
包装类
- 基本数据类型所对应的引用数据类型。
- Object可统一所有数据,包装类的默认值是null。
基本数据类型 | 包装类型 |
---|---|
byte | Byte |
int | Short |
short | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
类型转换与装箱、拆箱
基本类型——>引用类型装箱
引用类型——>基本类型拆箱
- 8种包装类提供不同类型间的转换方式:
- Number父类中提供的6个共性方法。
- parseXXX()静态方法。
- valueOf()静态方法
- 注意:需保证类型兼容,否则抛出NumberFormatException异常。
public class Demo{
public static void main(String[] args){
//装箱(基本类型转换为引用类型)
int num01 = 39;
//使用Integer装箱
Integer i1 = new Integer(num01);
//或者
Integer i2 = Integer.valueOf(num01);
//拆箱(引用类型转换为基本类型)
Integer i3 = new Integer(100);//装箱
int num02 = i3.intValue();//拆箱
/**
*以上操作是在JDK1.5之前使用的
*在JDK1.5之后,Java提供了自动装箱和拆箱
*/
/*自动装箱,拆箱操作*/
int num03 = 19;
//自动装箱
Integer i4 = num03;
//自动拆箱
int num04 = i4;
}
}
基本类型和字符串之间的转换
//1.基本类型转换成字符串
int n1 = 197;
//1.1使用+号
String s1 = n1+"";
//1.2使用Integer的toString()方法
String s2 = Integer.toString(n1);
//1.3toString()方法在这里有一个重载方法
/**
*toString(int i,int radix)
*/
String s3 = Integer.toString(n1,16);//c5
//转换为十六进制
//2.字符串转换为基本类型
String s4 = "150";
//2.1使用Integer.passXXX();
int n2 = Integer.parseInt(s4);//s4不能含有非数字字符
//boolean类型的字符串转换为基本类型
String s5 = "true";
boolean b1 = Integer.parseBoolean(s5);
/**
*如果s5是true,则b1为true,否则为false
*/
整数缓冲区(Integer缓冲区)
- Java预先创建了256个常用的整数包装类型对象。
- 在实际应用中,对已创建的对象进行复用。
Integer i1 = new Integer(100);
Integer i2 = new Integer(100);
System.out.println(i1==i2);//false
Integer i3 = 100;
Integer i4 = 100;
System.out.println(i3==i4);//true
Integer i5 = 200;
Integer i6 = 200;
System.out.println(i5==i6);//false
注意:自动装箱调用Integer.valueOf();
我们可以去valueOf();源码除寻求答案。
Integer.low = -128;
Integer.high = 127;
so····
是否有一种恍然大明白的感觉?
这就是Integer缓冲区(-128——127)共256个引用对象供你使用
String类
String类概述
- 字符串是常量,创建之后不可改变。
- 字符创字面值储存在字符串池中,可以共享。
- String s = “Hello”;产生一个对象,字符串池中储存。
- String s = new String(“Hello”);产生两个对象,堆、池各存储一个。
String say = "Hello";
String hee = "Hello";
此时,内存为:
由上图可知——字符创字面值储存在字符串池中,可以共享。
而当执行此操作
String say = "Hello";
//这里我们去掉hee
say = "nihao";
此时,内存为:
所以——字符串是常量,创建之后不可改变。
此时,字符串池中的"Hello"就是垃圾对象了。
当我们使用String s = new String();的时候,会在堆和字符串池中各创建一个对象(这里是便于理解,实际运行中堆中是没有对象的,只是指向字符串池)
如下图:
注意:这样会造成资源浪费。
so···
String say = new String("Hello");
String hee = new String("Hello");
System.out.println(say==hee);//false
String常用类
length()
- public int length();//返回字符串长度
String str = "Hello";
System.out.println(str.length());//5
charAt()
- public char charAt(int index);//根据下标获取字符
String str = "Hello";
System.out.println(str.charAt(4));//o
contains()
- public boolean contains(String str);//判断当前字符是否包含str
String str = "Hello";
System.out.println(str.contains("llo"));//true
toCharArray()
- public char[] toCharArray();//将字符串转换成为数组
String str = "Hello";
System.out.println(str.toCharArray());//Hello
indexOf()
- public int indexOf(String str);//查找str首次出现的下标,存在,返回该下标;不存在,则返回-1。
String str = "Hello";
System.out.println(str.indexOf("l"));//2
lastIndexOf()
- public int lastIndexOf(String str);//查找str最后一次出现的下标索引。
String str = "Hello";
System.out.println(str.lastIndexOf("l"));//3
trim()
- public String trim();//去掉字符串前后的空格
String str = " Hello! ";
System.out.println(str.trim());//Hello!
//but
String str1 = "Hel lo! ";
System.out.println(str1.trim());//Hel lo!
toUpperCase()
- public void toUpperCase();//将小写转成大写
String str = "Hello!";
System.out.println(str1.toUpperCase());//HELLO!
toLowerCase()
- public void toLowerCase();//将大写转成小写
String str = "HELLO!";
System.out.println(str.toUpperCase());//hello!
startWith()
- public boolean startWith(String str);//判断字符串是否以str开始。
String str = "java is number one!";
System.out.println(str.startWith("java"));//true
endWith()
- public boolean endWith(String str);//判断字符串是否以str结尾。
String str = "java is number one!";
System.out.println(str.startWith("one!"));//true
replace()
- public String replace(char oldChar,char newChar);//将旧字符串替换为新字符串。
String str = "java is number one!";
System.out.println(str.replace("j","J"));//Java is number one!
split()
- public String[] split(String str);//根据str做拆分。
String str = "java is number one!";
String[] strs = str.split(" ");
for(String s:strs){
System.out.println(s);
}
/**
* 输出结果:
* java
* is
* number
* one!
*/
可变字符串(StringBuffer和StringBuilder)
- StringBuffer:可变长字符串,JDK1.0提供,运行效率慢、线程安全。
- StringBuilder:可变长字符串,JDK1.5提供,运行效率快、线程不安全。
- 功能完全一样
运行效率比较:String<StringBuffer<StringBuilder
使用(常用方法)
append():追加
StringBuffer sb = new StringBuffer();
sb.append("java第一!");
sb.append("java世界第一!");
System.out.println(sb.toString());//java第一!java世界第一!
insert():添加(插入)
StringBuffer sb = new StringBuffer();
sb.append("java第一!");
sb.append("java世界第一!");
System.out.println(sb.toString());//java第一!java世界第一!
sb.insert(0."java");
System.out.println(sb.toString());//javajava第一!java世界第一!
replace():替换
StringBuffer sb = new StringBuffer();
sb.append("java第一!");
sb.append("java世界第一!");
System.out.println(sb.toString());//java第一!java世界第一!
//replace可以使用角标进行替换!(含头不含尾)
sb.replace(0,6,"Hello");
System.out.println(sb.toString());//Hello!java世界第一!
delete():删除
StringBuffer sb = new StringBuffer();
sb.append("java第一!");
sb.append("java世界第一!");
System.out.println(sb.toString());//java第一!java世界第一!
sb.delete(0,7);
System.out.println(sb.toString());//java世界第一!
BigDecimal
public class Demo05 {
public static void main(String[] args) {
double b1 = 1.0;
double b2 = 0.9;
System.out.println(b1-b2);
}
}
/**
* 运行结果:
* 0.09999999999999998
*/
出现上述情况是因为double是近似值存储,所以会存在误差,当需要精确计算时,double不再符合要求,此时就需要借助BigDecimal类
**位置:**java.math包中
**作用:**精确计算浮点数
**创建方式:**BigDecimal bd = new BigDecimal(“1.0”);
常用方法:
a.add(b);//加
a.subtract(b);//减
a.multiply(b);//乘
a.divide(b)//除
//如果除不尽,则使用:
divide(BigDecimal bd,int scal,RoundingMode mode);
/**
* 参数scal:指定精确小数点后几位
* 参数mode:指定小数部分的取舍模式
* 通常采用四舍五入:ROUND_HALF_UP
*/
Demo
BigDecimal bd1 = new BigDecimal("1.0");//一定要用字符串传入数据,不然依旧存在误差
BigDecimal bd2 = new BigDecimal("0.9");
System.out.println(bd1.subtract(bd2));
/**
* 运行结果:
* 0.1
*/
Date
-
Date表示特定的生煎,精确到毫秒。Date类中的大部分方法都已经被Calender类中的方法所取代。
-
时间单位
- 1s=1000ms
- 1ms=1000μs
- 1μs=1000ns
-
在JDK1.1之前,Date类有两个功能,它允许把日期解释为年、月、日、小时、分钟、和秒值。它也允许格式化和解析日期字符串。不过。这些函数的API不宜与实现国际化。从JDK1.1开始,应该使用Calender类实现日期和时间字段之间的转换,使用DateFormat类来格式化和解析日期字符串,Date中的相应方法已废弃。
after
Date date1 = new Date();//今天日期
Date date2 = new Date(date1.getTime-(1000*60*60*24));//昨天日期
boolean judge = date1.after(date2);
System.out.println(judge);
/**
* 运行结果:
* true
*/
before
Date date1 = new Date();//今天日期
Date date2 = new Date(date1.getTime-(1000*60*60*24));//昨天日期
boolean judge = date2.before(date1);
/**
* 运行结果:
* true
*/
compareTo
Date date1 = new Date();//今天日期
Date date2 = new Date(date1.getTime()-(1000*60*60*24));//昨天日期
int judge1 = date2.compareTo(date1);
int judge2 = date1.compareTo(date2);
int judge3 = date1.compareTo(date1);
System.out.println(judge1);
System.out.println(judge2);
System.out.println(judge3);
/**
* -1
* 1
* 0
*/
Calendar
- Calendar提供了获取或设置各种日历字段的方法
- 构造方法
- protected Calendar():由修饰符是protected,所以无法直接创建该对象。
方法名 | 说明 |
---|---|
static Calendar getInstance() | 使用默认时区和区域获取日历。 |
void set(int year,int month,int date,int hourofday,int minute,int second) | 设置日历的年、月、日、时、分、秒。 |
int get(int field) | 返回给定日历字段的值。字段比如年、月、日等。 |
void setTime(Date date) | 用给定的Date设置此日历的时间。Date-Calendar |
Date getTime() | 返回一个Date表示此日历的时间。Calendar-Date |
void add(int field,int amount) | 按照日历的规则,给指定字段添加或减少时间量。 |
long getTimeInMillies() | 毫秒为单位返回该日历的时间值。 |
getTime()
- 返回一个Date表示此日历的时间。Calendar-Date
//创建Calendar对象
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
System.out.println(date.toString());
//可以直接写成↓
System.out.println(calendar.getTime().toString());
/**
*运行结果
*Wed Nov 24 18:24:27 CST 2021
*Wed Nov 24 18:24:27 CST 2021
*/
get()
- 返回给定日历字段的值。字段比如年、月、日等。
//创建Calendar对象
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day1 = calendar.get(Calendar.DAY_OF_MONTH);
int day2 = calendar.get(Calendar.DAY_OF_YEAR);
int day3 = calendar.get(Calendar.DAY_OF_WEEK);
System.out.println("year:"+year);
System.out.println("month:"+month);
System.out.println("day1:"+day1);
System.out.println("day2:"+day2);
System.out.println("day3:"+day3);
/**
*运行结果
*year:2021
*month:10
*day1:24
*day2:328
*day3:4
*/
set()
- 设置日历的年、月、日、时、分、秒。
Calendar calendar = Calendar.getInstance();
calendar.set(2005,3,23,6,15);
System.out.println(calendar.getTime().toString());
//如果只想设置年月日,只键入年月日即可,例:
calendar.set(2017,3,23);//没有设置的值依照初始值显示
/**
*运行结果
*Sat Apr 23 06:15:50 CST 2005
*/
SimpleDateFormat
- SimpleDateFormat是一个以语言环境有关的方式来格式化和解析日期的具体类。
- 进行格式化(日期—>文本)、解析(文本—>日期)。
常用时间模式字母
字母 | 时间或日期 | 示例 |
---|---|---|
y | 年 | 2021 |
M | 年中月份 | 11 |
d | 月中天数 | 11 |
H | 1天中小时数(24小时制) | 11 |
h | 一天中小时数(12小时制) | 11 |
m | 分钟 | 11 |
s | 秒 | 11 |
S | 毫秒 | 111 |
//日期--->文本
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-mm-ss-sss");
Date date = new Date();
String str = sdf.format(date);
System.out.println(str);
//文本--->日期
Date date1 = sdf.parse("1995-11-26-55-25-659");
System.out.println(date1);
/**
*运行结果:
*2021-11-26-00-15-015
*Sun Nov 26 01:05:59 CST 1995
*/
System
- System系统类,只要用于获取系统的属性数据和其他操作,构造方法私有。
方法名 | 说明 |
---|---|
static void arraycopy(…) | 复制数组 |
static long currentTimeMillis(); | 获取当前系统时间,返回的是毫秒值 |
static void gc(); | 建议JVM赶快启动垃圾回收器回收垃圾。 |
static void exit(int status); | 退出JVM,如果参数是0表示正常退出,非0表示异常退出。 |
arraycopy()
-
可以实现数组的复制。
-
参数意义:
- src:原数组
- srePos:从那个位置开始复制
- dest:目标数组
- destPos:目标数组的位置(从那个数组开始放)
- length:复制的长度
int arr0 = {1,55,86,95};
int arr1 = new int[6];
System.arraycopy(arr0,0,arr1,2,4);
for(int a:arr1){
System.out.println(a);
}
/**
*运行结果:
*0
*0
*1
*55
*86
*95
*/
aurrentTimeMillis
- 获取毫秒数(1970-7-1至现在)
- 可以用做计时器,得知程序运行时长。
long start = System.currentTimeMillis();
···你的代码···
long end = System.currentTimeMillis();
System.out.println(end-start);//打印出时间
gc()
- 建议垃圾回收器回收垃圾对象
- 回收不回收不确定
exit()
- 退出JVM,0为正常退出,非0为异常退出。
System.out.println("eixt执行之前代码");
System.exit(0);
System.out.println("exit执行之后代码");
/**
*运行结果:
*exit执行之前代码
*/