文章目录
- 1、JDK、JRE、JVM有什么区别?
- 2、== 和 equals 的区别是什么?
- 3、两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
- 4、重写equals方法时为什么要重写hashCode?
- 5、final在java中有什么作用?
- 6、JAVA中的 Math.round(-1.5) 等于多少?
- 7、JAVA的基本数据类型有哪些?String是基本数据类型吗?
- 8、JAVA中操作字符串都有哪些类?它们有什么区别?
- 9、String str = "a" 和 String str=new String("a")有什么区别?
- 10、如何将字符串反转?
- 11、String类常用的方法有哪些?
- 12、抽象类必须有抽象方法吗?
- 13、普通类和抽象类有哪些区别?
- 14、抽象类能使用 final 修饰吗?
- 15、接口和抽象类有什么区别?
- 16、JAVA访问权限修饰符有哪些?说一下权限范围。
- 17、java 中 IO 流分为几种?
- 18、BIO、NIO、AIO 有什么区别?
- 19、Files的常用方法都有哪些?
1、JDK、JRE、JVM有什么区别?
简介:
- JDK(Java SE Development Kit):Java标准开发包。
- JRE( Java Runtime Environment) :Java运行环境。
- JVM(Java Virtual Mechinal):Java虚拟机。
区别:
- JDK=JRE+Java的开发工具(编译器javac以及其它的一些工具)。
- JRE=JVM+类库(lib)
2、== 和 equals 的区别是什么?
-
==解读
对于基本类型和引用类型==的效果是不同的
-
基本类型:比较的是值是否相同
-
引用类型:比较的是引用是否相同
-
-
equals解读
equals本质上就是==,如果一个类不重写equals方法,默认的equals方法实现就是==
Object的equals的实现方法:
public boolean equals(Object obj) { return (this == obj); }
-
代码演示
String x = "string"; String y = "string"; String z = new String("string"); System.out.println(x==y); // true System.out.println(x==z); // false System.out.println(x.equals(y)); // true System.out.println(x.equals(z)); // true
x==y 因为指向的是同一个引用所以结果为true
x==z 因为new String()开辟了新的内存空间,所以为false
因为String类重写了equals方法,所以equals比较的都是true
3、两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
不对,两个对象的 hashCode()相同,equals()不一定 true。
代码示例:
String str1 = "通话";
String str2 = "重地";
System.out.println(String.format("str1: %d | str2: %d", str1.hashCode(), str2.hashCode()));
System.out.println(str1.hashCode() == str2.hashCode());
System.out.println(str1.equals(str2));
输出结果:
str1: 1179395 | str2: 1179395
true
false
代码解读:很显然“通话”和“重地”的 hashCode() 相同,然而 equals() 则为 false,因为在散列表中,hashCode()相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等。
4、重写equals方法时为什么要重写hashCode?
首先我们要明确一些概念:
- 对象的hashCode相同,equals不一定相同
- 对象的hashCode不同,equals一定不同
- equals相同,hashCode一定相同
- equals不同,hashCode可能相同
不重写hashCode一般不会有什么影响,但一旦涉及到hash有关的计算,如放到HashSet集合中就可能出现与预期不一样的结果。
例如:
import java.util.Objects;
/**
* @author ZhengNC
* @date 2020/5/28 22:21
*/
public class Student {
private int age;
private String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(name, student.name);
}
}
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author ZhengNC
* @date 2020/5/28 22:26
*/
public class Test {
public static void main(String[] args) {
Student a = new Student(1, "a");
Student b = new Student(2, "a");
System.out.println(a.equals(b));
System.out.println(a.hashCode() == b.hashCode());
List<Student> list = new ArrayList<>();
list.add(a);
//如果不存在b,ArrayList直接调用equals方法判断是否存在
if (!list.contains(b)){
list.add(b);
}
System.out.println("--------list---------");
System.out.println(list);
Set<Student> set = new HashSet<>();
set.add(a);
//如果不存在b,HashSet先调用hashCode方法判断,
// 如果hashCode不一样就立刻认为不一样,就不再继续调用equals方法判断了
if (!set.contains(b)){
set.add(b);
}
System.out.println("--------set---------");
System.out.println(set);
}
}
运行结果:
true
false
--------list---------
[Student{age=1, name='a'}]
--------set---------
[Student{age=2, name='a'}, Student{age=1, name='a'}]
在Student类中重写了equals方法,没有重写hashCode方法。
在上面的测试方法中a和b的equals相同,hashCode不同。
判断相同的对象不重复放入集合中,ArrayList和HashSet的处理方式就不一样,ArrayList直接调用equals方法判断对象是否相同,所以ArrayList认为a和b是相同的。HashSet先调用hashCode方法判断,如果hashCode不同直接就认为两个对象不同,不再调用equals做判断。
5、final在java中有什么作用?
- final修饰的类为最终类,不可被继承,例如:java.lang.String。
- final修饰的方法不可被重写。
- final修饰的变量为常量,必须初始化,并且初始化之后的值不能被修改。
6、JAVA中的 Math.round(-1.5) 等于多少?
等于 -1,因为在数轴上取值时,中间值(0.5)向右取整,所以正 0.5 是往上取整,负 0.5 是直接舍弃。
7、JAVA的基本数据类型有哪些?String是基本数据类型吗?
JAVA共有8种基本数据类型:byte、short、int、long、float、double、char、boolean
它们的包装类型分别是:Byte、Short、Integer、Long、Float、Double、Character、Boolean
String不是基本数据类型。
8、JAVA中操作字符串都有哪些类?它们有什么区别?
有三种:String、StringBuilder、StringBuffer
String和StringBuilder、StringBuffer的区别是String声明的是不可变的字符串对象,每次修改值都会产生新的String对象,然后将指针指向新的String对象,而StringBuilder、StringBuffer可以在对象原有的基础上进行操作,因此对于经常改变字符串内容的情况下最好不要使用String。
StringBuilder和StringBuffer的最大区别是StringBuilder是非线程安全的,StringBuffer是线程安全的,StringBuilder的效率要高于StringBuffer,因此在单线程环境中建议使用StringBuilder,在多线程环境下建议使用Stringbuffer。
9、String str = “a” 和 String str=new String(“a”)有什么区别?
String str="a"是把“a”分配到常量池中,而String str=new String(“a”)是在常量池中创建“a”之后再复制到堆内存中,然后返回堆内存的引用给str。
String str1 = new String("a");
String str2 = "a";
String str3 = str1.intern();//返回字符串对象的规范形式,就是返回常量池中的那一份对象
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str2 == str3);
运行结果:
false
false
true
10、如何将字符串反转?
使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。
11、String类常用的方法有哪些?
- indexOf():返回指定字符的索引。
- charAt():返回指定索引处的字符。
- replace():字符串替换。
- trim():去除字符串两端空白。
- split():分割字符串,返回一个分割后的字符串数组。
- getBytes():返回字符串的 byte 类型数组。
- length():返回字符串长度。
- toLowerCase():将字符串转成小写字母。
- toUpperCase():将字符串转成大写字符。
- substring():截取字符串。
- equals():字符串比较。
12、抽象类必须有抽象方法吗?
不需要,抽象类不一定非要有抽象方法。
12.1、没有抽象方法的抽象类可以直接实例化吗?
不可以。
13、普通类和抽象类有哪些区别?
- 普通类不能包含抽象方法,抽象类可以包含抽象方法。
- 抽象类不能直接实例化,普通类可以直接实例化。
14、抽象类能使用 final 修饰吗?
不能,抽象类定义出来就是为了让其它类继承的,而final修饰的类不能被继承,因此final不能修饰抽象类。
15、接口和抽象类有什么区别?
-
实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。
-
构造函数:抽象类可以有构造函数;接口不能有。
-
main 方法:抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方法。
public abstract class MyAbstract { public static void main(String[] args) { System.out.println("abstract"); } }
-
实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
-
访问修饰符:
接口中的方法默认使用 public 修饰,并只能是public修饰;
抽象类中的方法默认为default修饰,普通方法可以是任意访问修饰符,而抽象方法不能是private修饰。
16、JAVA访问权限修饰符有哪些?说一下权限范围。
修饰符 | 类内部 | 同一包 | 子类 | 任何地方 |
---|---|---|---|---|
private | 是 | 否 | 否 | 否 |
default | 是 | 是 | 否 | 否 |
protected | 是 | 是 | 是 | 否 |
public | 是 | 是 | 是 | 是 |
17、java 中 IO 流分为几种?
按功能来分:输入流(input)、输出流(output)。
按类型来分:字节流和字符流。
字节流和字符流的区别是:字节流按 8 位传输以字节为单位输入输出数据,字符流按 16 位传输以字符为单位输入输出数据。
18、BIO、NIO、AIO 有什么区别?
- BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
- NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
- AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
19、Files的常用方法都有哪些?
- Files.exists():检测文件路径是否存在。
- Files.createFile():创建文件。
- Files.createDirectory():创建文件夹。
- Files.delete():删除一个文件或目录。
- Files.copy():复制文件。
- Files.move():移动文件。
- Files.size():查看文件个数。
- Files.read():读取文件。
- Files.write():写入文件。