API概述
API(application Programming Interface, 应用程序编程接口),是一些预先定义的函数。目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节
比如我需要在一个程序里面嵌入语音识别交互功能,那么这个功能如果让我们自己从零开始实现,肯定是不现实的,所以市场上面就出现了提供这个语音识别功能的公司,这些公司会提供给应用程序编程的接口,大家把这些类称为Xxx Voice API. 我们只需要调用相应的方法就可以实现我们想做的事情,底层实现不需要我们关注。本章涉及的java API指的就是JDK中提供的各种功能的java类
一 Object
1. 构造方法:
public Object()
2. 成员方法
2.1 方法介绍
默认地址值根据特定算法运算得到的一个整数值),可重写(源码不可见,此方法是用native修饰,用native修饰的方法一般都是用其他语言实现(C),效率高)
public final Class getClass() 返回字节码对象(Class对象),里面包含了类中的所有信息,不能被重写(此方法使用final修饰)
public String toString(): 返回对象的字符串形式(默认是全类名+地址值),可重写
public boolean equals(Object obj): 判断两个对象是否是同一个对象,默认用==实现,可重写
1. hashCode:
一般用hashCode判断两个对象是不是同一个对象,如果hashCode不相等,则肯定不是一个对象,如果hashCode相等,则一定是同一个对象
public class ObjectClass {
public static void main(String[] args) {
Person p = new Person();
Person p1 = new Person();
System.out.println(p.hashCode()); //804564176
System.out.println(p1.hashCode()); // 1421795058
}
}
class Person{
String name;
}
可见对象p和对象p1不是同一个对象(注释为得到的hashCode值)
2. getClass:
其余代码同上
Class clazz = p.getClass(); // 获取p的字节码对象 Person类的字节码对象
System.out.println(clazz); // class com._51doit.javase.day11.Person
System.out.println(clazz.getSimpleName()); // Person
System.out.println(clazz.getName()); // com._51doit.javase.day11.Person
System.out.println(clazz.getPackage()); // package com._51doit.javase.day11
3. toString:
System.out.println(p.toString()); //com._51doit.javase.day11.Person@2ff4acd0 全类名+@+hashcode值的16进制(hashcode值是10进制)
System.out.println(p); //com._51doit.javase.day11.Person@2ff4acd0
println()内部实现是toString,toString源码如下,由此可理解打印的结果
4. equals
格式:对象1.equals(对象2)
(1)equals和 ==
equals:判断两个对象是否是同一个对象(默认是==实现的,可重写)
==:连接基本数据类型(比较的是值)
连接引用数据类型(比较的是地址值)
(2)equals和hashCode的用法
一般我们在比较对象是否是同一个对象的时候,是同时使用hashCode和equals
a. 先用hashCode 作比较:
如果hashCode 不同: 一定不是同一个对象
如果hashCode 相同: 不一定,继续比较equals:( 这样比较的原因:hashCode方法的实现是C语言,效率高)
equals:
true 说明是同一个对象
false: 不是同一个对象
b. 为了保证equals 和hashCode 结果的一致性
我们在重写equals 方法的同时,也要重写hashCode,约定俗称(即当equals定义相等的条件改变时,hashCode也要改变)
自动重写:右键-->source-->generate hashCode and equals
练习
定义一个Teacher类,并创建2个对象,如果两个对象的属性值相同,就认定为同一个对象,打印对象:System.out.println(t),打印的格式为(姓名:张三,年龄:18,工资:20000)
public class Exer1 {
public static void main(String[] args) {
Teacher t1 = new Teacher();
Teacher t2 = new Teacher();
System.out.println(t1);
if(t1.hashCode() == t2.hashCode()) {
if(t1.equals(t2)) {
System.out.println("true");
}else {
System.out.println("false");
}
}else {
System.out.println("false");
}
}
}
class Teacher{
String name="张三";
int age = 18;
double salary = 20000;
public String toString() {
return "姓名:"+name+",年龄:"+age+",工资:"+salary;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
long temp;
temp = Double.doubleToLongBits(salary);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Teacher other = (Teacher) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (Double.doubleToLongBits(salary) != Double.doubleToLongBits(other.salary))
return false;
return true;
}
}
View Code
二 Scanner
scanner表示键盘录入,但若输入的数据类型与表达式不同则会报错,以int为例
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
// 此处a若输入一个非int值时就会报错
解决方法
//加个条件判断
Scanner sc= new Scanner(System.in);
if(sc.hasNextInt()){
int a = sc.nextInt();
}
三. String
1. String类概述:
字符串是由多个字符组成的一串数据(字符序列,字符串可以看成是字符数组)
2. 构造方法
(1)public String()
(2)public String(byte[ ] bytes)
(3)public String(byte[ ] bytes, int offset, int length)
(4)public String(byte[ ] value)
(5)public String(char[ ] value, int offset, int count)
(6)public String(String original)
案例
public class StringDemo {
public static void main(String[] args) {
}
}
方法体中添内容
a 构造方法1
String str = new String();
System.out.println(str);
// 打印结果为空,所以第一个构造方法对应空字符串
其构造方法源码如下
b 构造方法2(byte数组转为字符串)
byte[] bs = new byte[] {97,98,99};
String str1 = new String(bs);
System.out.println(str1);
// 运行的结果为abc
此处构建字符串是用数组中编码所代表的字符来构建字符串,编码97在ascii码中代表a
c 构造方法3(byte类型转换的字符串进行切片)
String str2 = new String(bs,1,2);//offset=1,length=2表示从数组索引为1的编码开始取2位
System.out.println(str2);
// 运行结果:bc
d 构造方法4(char类型数组转为字符串)
char[] chs = new char[] {'哈','哈', '大','笑','哭','笑','不','得'};//右边可以省略new char
String str3 = new String(chs);
System.out.println(str3);
// 运行结果:哈哈大笑哭笑不得
e 构造方法5(带偏移量以及count的char数组转为字符串)
System.out.println(new String(chs,3,3));
// 运行结果:笑哭笑
f 构造方法6(字符串转字符串,即赋值)
String str4 = new String("你好,世界");
System.out.println(str4);
相当于将“你好,世界”赋值给了str4
3 此种赋值方式(str4)与直接赋值(str=“你好,世界”)有什么区别?
存放位置不一样,直接赋值的str存放在常量池,而str4的形式是创建了一个新对象,其存放位置为堆。
案例
public class StringDemo2 {
public static void main(String[] args) {
String str = "你好,世界"; // 存放在常量池(jdk1.6位置为方法区,1.7为堆内存中,1.8以后放在一个元空间)
String str1 = new String("你好,世界");
System.out.println(str == str1);
}
}
// 运行结果:false
若另外创建一个内容相同的常量字符串str2,其地址值是否和ste一样?答案:一样
String str2 = "你好,世界";
System.out.println(str == str2);
//运行结果:true
注意字符串中的equals比较的是字符串内容是否相等
System.out.println(str.equals(str1));
运行结果是true
同理,equals重写了,相应的hashCode方法也被重写了,str和str1的hashCode值也相等
System.out.println(str.hashCode() == str1.hashCode());
// 运行结果:true
4. String内存分配
(1)直接赋值:存放在常量池中,先在常量池中找该字符是否存在,如果存在,直接用这个字符串,如果没有,则创建一个新的,相同的内容,只有一份
(2)new:存放在堆内存中,new几个就开辟几块空间,也就是几个地址值
5. 面试题
第4行代码中的s存在那一块?
1 public class StringDemo3 {
2 public static void main(String[] args) {
3 String s = "hello"; // 常量池
4 s += "world"; // s = s+ world 堆内存
5 }
6 }
为了弄清第4行代码是怎么运行的,找到这个文件的.class,进行反编译(将计算机能看懂的文件转换成人能看懂的内容),用XJAD软件打开即可
在eclipse上找.java文件的.class文件的流程
特定.java文件上右键--->show In----->System Explorer,即可得到.java文件所在的目录,如下
在地址栏那一块点击src上一层的javase,即可出现如下界面
这个时候点击bin文件夹,即可找到相应的.class文件
利用xjad进行反编译可得:
由19行可知,s存在堆内存中
5. String的判断功能
String
(1)boolean equals(Object obj):比较字符串的内容是否一样
(2)boolean equalsIgnoreCase(String str):忽略大小写比较字符串的内容
(3)boolean contains(String str):某个字符串是否包含另一内容
(4)boolean startsWith(String str):是否以。。。开头
(5)boolean endsWith(String str):是否以。。。结尾
(6)boolean isEmpty():判断字符串是否为空
案例
public class StringDemo4 {
public static void main(String[] args) {
String str = "abc";
String str1 = "abc";
System.out.println(str.equals(str1)); // true,equals判断的是字符串的内容是否相同
System.out.println("abc".equalsIgnoreCase("ABc")); // true
System.out.println("abcdefgh".contains("def")); //true
System.out.println("Abcsd".startsWith("Ab")); //true
System.out.println("Abcsd".endsWith("sd")); // true
System.out.println("abc".isEmpty()); // false
}
}
练习
模拟登陆,给三次机会,并提示还有几次机会
public class Login {
public static void main(String[] args) {
String name = "老王";
String pwd = "123456";
Scanner sc = new Scanner(System.in);
for(int i=0;i<3;i++) {
// 请输入您的姓名
System.out.println("请输入您的姓名");
String userName = sc.nextLine();
// 请输入您的密码
System.out.println("请输入您的密码");
String userPwd = sc.nextLine();
if(userName.equals(name) && userPwd.equals(pwd)) {
System.out.println("登陆成功");
break;
}else {
if(i<2) {
System.out.println("用户名或密码错误,您还有"+(2-i)+"次机会");
}else {
System.out.println("今日机会已用完");
}
}
}
}
}
6. 字符串的获取功能
(1)int length(): 获取字符串的长度
(2)char charAt(int index) : 返回index对应的字符
(3)int indexOf(int ch): 返回ch对应的字符,第一次出现的索引值
(4)int intdexOf(String str): 返回str第一次出现的索引值
(5)int indexOf(int ch, int fromIndex)
(6)int indexOf(String str, int fromIndex)
(7)String substring(int start): 字符串的截取从start到最后
(8)String substring(int start, int end): 包含start,不包含end