API
什么是API?
java中组件的层次结构
如何访问API
==>(点这里)API文档入口https://docs.oracle.com/en/java/javase/11/docs/api/index.html
打开后可以看到里面的名字不是以java开头就是jdk开头的。
然后我们随便打开一个文件,可以看到上面显示的是package
再打开一层
可以看到interface和class
这说明了java的组件层次结构是由 module 到 package 再到 package/interface的。
API对我们学习java有着十分重要的作用,上面汇集了各种类库的用法,相当于一本说明书。大家如果有不懂的地方可以上去查阅。
Object类
简介
Object类
概述:类层次结构最顶层的基类,所有类都直接或间接继承Object类
构造方法:
public Object()
成员方法:
int hashCode():返回对象的哈希码值。
Class<?> getClass():返回该调用者的字节码文件对象。
String toString():返回该对象的字符串表示形式。
boolean equals():比较两个对象是否相等。
我们可以在API中搜索它的用法
如果上面的概念看不懂往下翻,还可以看到该方法使用的详情和细节。
Object都是以地址值为基础的,所以建议子类对Object类进行重写,不然将毫无意义。
package cn.object.demo;
import cn.homework.Person;
/* Object类
概述:类层次结构最顶层的基类,所有类都直接或间接继承Object类
构造方法:
public Object()
成员方法:
int hashCode():返回对象的哈希码值。
Class<?> getClass():返回该调用者的字节码文件对象。
String toString():返回该对象的字符串表示形式。
boolean equals():比较两个对象是否相等。
注意:
java.lang包下的类可以直接使用,不需要导包。
*/
public class Test {
public static void main(String[] args) {
//int hashCode():返回对象的哈希码值。
Object obj1 = new Object();
Object obj2 = new Object();
int code1 = obj1.hashCode();
int code2= obj2.hashCode();
System.out.println("code1 = " + code1);
System.out.println("code2 = " + code2);
System.out.println("-----------------------");
//Class<?> getClass():返回该调用者的字节码文件对象。一个类只有一个字节码。
Class clazz1 = obj1.getClass();
Class clazz2 = obj2.getClass();
System.out.println("clazz1 = " + clazz1);
System.out.println("clazz2 = " + clazz2);
System.out.println("-----------------------");
//String toString():返回该对象的字符串表示形式。
// 地址值的组成:全类名 + @ + 该对象的哈希码的无符号十六进制形式
String s1 = obj1.toString();
String s2 = obj2.toString();
System.out.println("s1 = " + s1);
System.out.println("s2 = " + s2);
System.out.println("------------------------");
//boolean equals():比较两个对象是否相等,默认比较的是地址值。
boolean b1 = obj1.equals(obj2);
System.out.println("b1 = "+ b1);
}
}
/*
所有类都直接或间接继承Object类:
class Person extends Object {
}
class Student extends Person{
}
这里Person类直接继承Object而Student类间接继承Object
*/
用JavaBean类重写Object类的方法
需求:定义一个标准的javaBean类,并在测试类中进行测试
测试类:学生Student
属性:id(学号),name(名字),score(成绩)
首先先把基本的代码写好
package cn.object.demo;
public class Student {
private int age;
private String name;
private float score;
public Student() {}
public Student(int age, String name, float score) {
this.age = age;
this.name = name;
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getScore() {
return score;
}
public void setScore(float score) {
this.score = score;
}
//重写Object类中的toString方法。
//重写Object类中的equals方法。
}
主函数:
package cn.object.demo;
/*
定义一个标准的javaBean类,并在测试类中进行测试
测试类:学生Student
属性:id(学号),name(名字),score(成绩)
*/
public class Test2 {
public static void main(String[] args) {
Student s1 = new Student();
//没重写toString方法时输出对象的情况
System.out.println(s1);
System.out.println(s1.toString());
}
可以清楚的看到没有重写Object类中的 toString 时,输出 s1 等同于输出其toString 值,这也证明了输出 s1 就是输出其toString() 的值
后面我们补全重写toString里面的代码
可以使用便捷方式。
//重写Object类中的toString方法。
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", score=" + score +
'}';
}
现在来看看输出结果
可以看到输出结果有所改变。
接下来是重写equals方法,使用其比较成绩的值(注意,这是自行修改的,没有按照编译器的固定修改模式)。
代码部分
//重写Object类中的equals方法。
@Override
public boolean equals(Object obj){ //比较s1与s2中的成绩s1.equals(s2)
/*
this:谁调用就表示谁->s1
obj:s2
向上转型:把子类创建的对象的引用放到一个父类的对象中向下转型反过来
*/
Student s2 = (Student)obj;//向下转型操作,把父类创建的对象引用放到子类的对象中
return this.score == s2.score;
}
输出结果:
Student s2 = (Student)obj;
这里有一行代码可能大家觉得很奇怪
为什么要进行这一项操作呢?
正常来说不是直接return就可以了吗?
可以看到如果直接return就会报错,那这是为什么呢?
这就涉及到了向上和向下转型的知识点了
【复习】 向上转型:把子类创建的对象的引用放到一个父类的对象中,就得到了该对象的向上转型。 =号的右边传到左边。
注:向上转型不能操作子类新增的成员和方法,也就是失去了部分属性和功能。
问题:
当我们用Student s2 作为参数时,就有下面语句
Object obj = Student s2;这就进行了向上转型
然后Student是子类,新增了Score成员
因为向上转型后不能操作子类新增的成员和方法
因此obj不能使用Student中的socre成员变量,因此会报错
解决
需要语句能正常运行,就要进行向下转型
把父类的对象引用放到子类的对象中(就是从Object变回Student)这样就可以了。
但是在实际的编程中,我们不可能只用equals只比较一个量值,这样代码会十分不严谨,因此在实际编程中我们需要比较多个量,所以重写equals方法最好使用系统自带重写方法。
下面进行操作展示:
选择后会弹出一个窗口
下面来说说这些选项的作用
第一个是Template类是模板类一般选用默认就ok
第二个是如果你这个类中本来就有一个父类的话,是否采用父类的参数进行比较,没有的话或者不需要的话就不用选
第三个是说在比较的时候是否使用getter来实现,如果在本类中重写可以直接使用属性,那就不用选。
这个窗口是选择是否为非空
重写之后的代码如下:
@Override
public boolean equals(Object o) {
//比较两个地址值是否一致,如果一致就直接返回true,提高效率
if (this == o) return true;
//比较两个对象是否是同一个类型。
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;//向下转型
return age == student.age &&
Float.compare(student.score, score) == 0 &&
name.equals(student.name);
}
解释
1.首先,比较两个对象的地址值,就相当于比较是不是同一个人,如果是那下面的属性就没有任何比较意义,这样提高了程序的运行效率
2.然后用getclass比较字节码文件对象,就是判断对象是否是同一类型(提醒一下,一个类只有一个字节码对象,你细品这段代码的上下桥接性)
3.最后,前两项if都通过后就是比较属性值了,直接用return语句实现,至于后面为什么name使用equals来比较,因为name属性String类,String也是Object的子类,所以可以直接调用String中的equals方法。(妙啊!)
结果:
Scanner类
概念
Scanner类可以在API中进行查询
—>点这里可以进入Scanner的API
翻译可能有点别扭
hasNextXxx和nextXxx
下面来展示一下用Scanner中的hasNextXxx和nextXxx做一个判断输入数据是否正确的程序
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
System.out.println("请输入一个int型数据");
Scanner sc = new Scanner(System.in);//标准的输入流,默认指向键盘,注意这时候就触发了键盘的输入。(注意需要导包)
if(sc.hasNextInt()) {
int i = sc.nextInt();
System.out.println("i = " + i );
}
else
System.out.println("你输入的数据类型有错误请重新输入");
}
}
结果
String NextLine与String Next
下面展示一下String NextLine与String Next的以以换行符作为分隔符和以空白字符作为分隔符区别
代码展示
import java.util.Scanner;
/*
String nexLine():获取下一行字符,以换行符作为分隔符(即结束标记)
String next():获取下一个输入项,以空白字符作为分隔符(即结束标记)
*/
public class Test2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入字符串:");
String str1 = sc.nextLine();
System.out.println("str1 = " + str1);
}
import java.util.Scanner;
/*
String nexLine():获取下一行字符,以换行符作为分隔符(即结束标记)
String next():获取下一个输入项,以空白字符作为分隔符(即结束标记)
*/
public class Test2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入字符串:");
/*String str1 = sc.nextLine();
System.out.println("str1 = " + str1);*/
String str2 = sc.next();
System.out.println("str2 = " + str2);
}
}
对比很明显str1输出了全部 str2只输出了一部分,所以这就是String NextLine与String Next的以以换行符作为分隔符和以空白字符作为分隔符区别。
String类
简介
同样在API中寻找使用说明
String类的判断功能
String类的获取功能
String类型的转换功能
String Builder与String Buffer类
简介
Date和Calendar类
介绍
进入API
点这里
Date类的演示
/*
Date
简介:
日期类,用于操作时间相关信息。构造方法:
Date():构造一个日期对象,当前系统时间,精确到亳秒
Date(long):构造一个日期对象,时间为自“1970年1月1日00:00:00 GMT”起,至指定参数的毫秒数成员方法
long getTime():将日期对象转换成对应时间的毫秒值
Calendar类
简介:
日历类.用于操作日期相关信息。成员方法
static Calendar getInstance():根据当前系统时区和语言环境获取日历对象int get(int field):
返回给定日历字段的值
void set(int field, int value):将给定的日历字段设置为指定的值
*/
import java.util.Date;
public class Time {
public static void main(String[] args) {
Date date1 = new Date();
System.out.println("date 1 = " + date1);//返回系统的时间
long time = date1.getTime();//会随时间而变化,这是date1的毫秒值表示形式
System.out.println("time " + time);
Date date2 = new Date(1606229521931l);//输入毫秒值,时间会定在你输入的值
System.out.println("date2 = " + date2);
long time2 = date2.getTime();
System.out.println("time2 = "+time2);//输出的毫秒值亦如此。
}
}
注意事项都在代码里了
Calendar类演示
注意Calendar类属于抽象类不能直接创建对象
如果直接创建,系统就会提醒你这是一个抽象类。
但是我们可以使用getInstance()函数实现这个功能,因为这个方法是静态的所以可以直接使用
import java.util.Calendar;
import java.util.Date;
public class Time {
public static void main(String[] args) {
Calendar c1 = Calendar.getInstance();
System.out.println("c1 = " + c1 );
}
}
然后再用这个对象里的函数实现相关的功能,例如使用get()函数获取年月日。
import java.util.Calendar;
import java.util.Date;
public class Time {
public static void main(String[] args) {
Calendar c1 = Calendar.getInstance();
System.out.println("c1 = " + c1 );
int year = c1.get(Calendar.YEAR);
int month = c1.get(Calendar.MONTH);
int day = c1.get(Calendar.DATE);
System.out.println("year = " + year +",month = " + month + ",day = " + day);
}
}
set()函数,改到指定的年月日
import java.util.Calendar;
import java.util.Date;
public class Time {
public static void main(String[] args) {
Calendar c1 = Calendar.getInstance();
System.out.println("c1 = " + c1 );
c1.set(2021,1,1);
int year = c1.get(Calendar.YEAR);
int month = c1.get(Calendar.MONTH);
int day = c1.get(Calendar.DATE);
System.out.println("year = " + year +",month = " + month + ",day = " + day);
}
}
基本类型的包
简介
例如把基本类型byte转换成包装类型(引用类)Byte就叫装箱
反过来就叫拆箱
关于引用类和基本类
8种基本类型
一、4种整型
byte 1字节 -128——127
short 2 字节 -32,768 —— 32,767
int 4 字节 -2,147,483,648 ——2,147,483,647(超过20亿)
long 8 字节 -9,223,372,036,854,775,808——9,223,372,036854,775,807
注释:java中所有的数据类所占据的字节数量与平台无关,java也没有任何无符号类型
二、 2种浮点类型
float 4 字节 32位IEEE 754单精度(有效位数 6 – 7位)
double 8 字节 64位IEEE 754双精度(有效位数15位)
三、1种Unicode编码的字符单元
char 2 字节 整个Unicode字符集
四、1种真值类型
boolean 1 位 True或者false
3种引用类型
类class
接口interface
数组array
一、类Class引用
可以是我们创建的,这里我不多讲,主要是讲解几个java库中的类
Object :Object是一个很重要的类,Object是类层次结构的根类,每个类都使用Object作为超类,所有对象(包括数
组)都实现这个类的方法。用Object可以定义所有的类
如:
Object object= new Integer(1); 来定义一个Interger类
Integer i=(Integer) object; 在来把这个Object强制转换成Interger类
String :String类代表字符串,Java 程序中的所有字符串字面值(如"abc")都作为此类的实例来实现。检查序列的单
个字符、比较字符串、搜索字符串、提取子字符串、创建字符串副本、在该副本中、所有的字符都被转换为 大 写或小写形式。
Date :Date表示特定的瞬间,精确到毫秒。Date的类一般现在都被Calendar 和GregorianCalendar所有代替
Void :Void 类是一个不可实例化的占位符类,它保持一个对代表 Java 关键字 void 的 Class 对象的引用。
同时也有对应的Class如:Integer Long Boolean Byte Character Double Float Short
代码部分
public class Test {
public static void main(String[] args) {
int a = 10;
Integer i1 = new Integer(a);//装箱
int b = i1.intValue();//拆箱
System.out.println("a = " + a + ",b = " + b + ",i1 = " + i1);
//简化写法
Integer i2 = 10;//装箱
int c = i2; //拆箱
System.out.println("i2 = " + i2 + "c = " + c );
}
}
public class Test {
public static void main(String[] args) {
String a = "10";
int b = Integer.parseInt(a);
System.out.println("b = " + b);
}
}
注意Character类无parse函数
因为字符串转Char类可以通过String类的函数进行转换