Java 基础(弄懂很重要,话不多说,进入正题,(★)表示重要程度)
1. JDK 和 JRE 的区别? (★★)
- JDK: Java Development Kit 的简称,Java 开发工具包,包括( java的开发环境 )和(java的运行环境)
- JRE: Java Runtime Environment 的简称,Java 运行环境,为 Java 的运行提供了所需环境。
实际上,JDK 中包含了 JRE,同时还包含了编译 Java 源码的编译器 Javac,很多 Java 程序调试和分析的工具。总之:如果运行 Java 程序,只需要安全 JRE 就可以了,如果你需要编写 Java 程序,需要安装 JDK 。
2. == 和 equals 的区别? (★★★★★)
== :
对于基本类型(8种)和 引用类型,== 的作用不相同,举例
- 基本类型 : 比较的是值是否相同;
- 引用类型: 比较的是引用的地址是否相同(引用指向的对象);
示例:
public class TestDemo {
public static void main(String[] args) {
//引用类型
String a = "hello"; //一号hello
String b = "hello"; //一号hello
String c = new String("hello"); //二号hello
//==
System.out.println(a==b); //true,同一个hello
System.out.println(a==c); //false,不同的hello地址
//equals,比较值是否相同,和它存在那个内存空间无关
System.out.println(a.equals(b)); //true
System.out.println(a.equals(c)); //true
System.out.println(a.equals("hello")); //true
System.out.println("hello".equals(a)); //true
}
}
引用类型中, a 和 b 指向的是同一个引用,虽有 a == b为 true,c 为重新 new 的新的对象,并且重新开辟了内存空间,此时内存空间至少有俩 hello,a==c 为false,而 equals 比较的一直都是空间中的值,都为 true.
equals :
equals 本质为 ==,只是重写了 equals 方法,变成了值比较
示例:
class User{
private String name;
//添加有参构造,可以在new 对象时给name赋值
public User(String name) {
this.name = name;
}
//get,set方法,添加和获取封装对象中的数据
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class TestDemo1 {
public static void main(String[] args) {
User u1 = new User("张三");
User u2 = new User("张三");
System.out.println(u1.getName()+","
+u2.getName()+","
+u1.getName().equals(u2.getName()));//张三,张三,true
System.out.println(u1+","
+u2+","
+u1.equals(u2));//aaaa.User@15db9742,aaaa.User@6d06d69c,false
}
}
u1是User引用,u2是User引用,本质也是==,先比较==是否成立
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
如果引用指向的是String或其他固定的类型,返回true
public class TestDemo1 {
public static void main(String[] args) {
String u3 = new String("张三");
String u4 = new String("张三");
System.out.println(u3.equals(u4)); //true
}
}
String 的equals源码,当为String类型时,示
public boolean equals(Object anObject) {
//如果== 成立,则成立
if (this == anObject) {
return true;
}
//String 类型
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
总结:
- == 对于基本类型来说比较 值,对于引用类型来说是比较 引用
- equals默认是比较 引用,只是 String,Integer 等类型重新写了 equals 方法,一般情况下equals 比较的是 值。
3.两个对象的 hashCode() 相同,则 equals() 一定为 true 么?
不一定为true:
- 示例
public class TestDemo2 {
public static void main(String[] args) {
String s1 = "张三";//s1.hashCode()=774889
String s2 = "李四";//s2.hashCode()=842061
String s3 = "张三";//s3.hashCode()=774889
//特殊
String t1 = "通话";
String t2 = "重地";
System.out.println(String.format(
"t1 : %d | t2 : %d", t1.hashCode(),t2.hashCode()));//t1 : 1179395 | t2 : 1179395
System.out.println(t1.equals(t2));//false
}
}
**4. Java 种的8种数据类型? String属于什么类型?**★★★★
8种数据类型:
- 整数型(4种):byte(8位)、short(16)、int(32)、long(64)
- 浮点数(2种):float(单精度,32) 、double(双精度,64)
- 字符类型(1种):char(16位)
- 布尔类型(1种):boolean(默认false)
String 属于对象
延伸:
5种引用类型(对象类型) - 类
- 接口
- 数组
- 枚举
- 标注
5. final 在Java 中有什么作用?
- 修饰的类为最终类,该类不能被继承
- 修饰的方法不能被重写(子类中不能重写父类中final修饰的方法)
- 修饰的变量叫常量,常量必须初始化(赋值),赋值后就不能被修改。
6.java 中的Math.round(-0.5)等于多少?
示例:
public class TestDemo4 {
public static void main(String[] args) {
//负数0.5舍去
double c = -1.4;
double a = -1.5;
double b = -1.66;
System.out.println(Math.round(c));//-1
System.out.println(Math.round(a));//-1
System.out.println(Math.round(b));//-2
}
}
总结:负数时,在数轴上往右取整,0.5也舍去。
7 . String s = “hello” 和 String s = new String(“hello”)的区别?
内存的分配方式不一样
- String s = “hello”,会将hello分配到常量池中
- String s = new String(“hello”),会将hello分配到堆内存中。
8."abcdef"字符串反转?
可以使用StringBuilder或StringBuffer的reverse()方法。
示例
public class TestDemo4 {
public static void main(String[] args) {
String s ="abvde";
String s1 = s+"fg"; //不能直接拼接,对s没影响
//StringBuffer线程安全
StringBuffer sbf = new StringBuffer(s);
sbf.append("fg");//字符串拼接,不会重新new对象
System.out.println(sbf.reverse());//gfedcba
//StringBuilder线程不安全
StringBuilder sbd = new StringBuilder(s);
sbd.append("fg");
System.out.println(sbd.reverse());//gfedcba
}
}
9. String、StringBuffer、StringBuilder 的区别?
- String : 声明的是不可变对象,每次操作它都会产生新的对象,然后引用指向新的String对象,而原来的对象将会保留。
- StringBuffer、StringBuilder都可以在原来的对象上进行操作,拼接等,故要经常改变字符串的内容的不要使用String类型
- StringBuffer 是线程安全的,性能低。StringBuilder是非线程安全的,性能高。
- 单线程下推荐用StringBuilder,多线程推荐用StringBuffer。】
10.你在工作中,用过哪些String类的方法?
- equals() : 字符串比较。
- trim() : 去除字符串两端的空格。
- split() : 分割字符串,返回一个分割后的字符串数组。
- subString() : 截取字符串。
- length() : 返回字符串长度。
- toLowerCase() : 将字符串转化成小写字母,与它相反的是toUpperCase()
- getBytes() : 返回字符串的byte类型数组
- indexOf() : 返回指定字符的索引
- replace() : 字符串替换。
- charAt() : 返回指定索引出的字符。
示例
public class TestDemo5 {
public static void main(String[] args) {
String s = " ABC abc ABC "; //两边各俩空格,中间有俩空格
int t = s.length(); //字符串长度 t=15
String s1 = s.trim(); //去除字符串两边的空格 "ABC abc ABC"
//s1="ABC abc ABC"
int i = s1.indexOf("C"); //从0开始,第一个出现的字母,i=2
char c = s1.charAt(2); //"C"
byte[] bytes = s1.getBytes();
String up = s1.toUpperCase(); //ABC ABC ABC
String lo = s1.toLowerCase();//abc abc abc
String[] split = s1.split(" ");//ABC abc ABC
String substring = s1.substring(2);//填写下标 C abc ABC,截取2位剩余后面返回
String s2 = "ABC abc ABC";//true
StringBuilder sbd = new StringBuilder("ABC abc ABC");//false
}
}
11. 说一下抽象类?
- 抽象类用来描述一种类型应该具备的基本特征与功能, 具体如何去完成这些行为由子类通过方法重写来完成。
- 抽象方法指只有功能声明,没有功能主体实现的方法。
- 具有抽象方法的类一定为抽象类,抽象类不一定有抽象方法
示例
abstract class Pet{ //把宠物抽象,然后加一个抽象的吃方法
public abstract void eat();//抽象方法没有方法体,不能有{},分号结束
}
class Dog extends Pet{ //继承抽象类。一定要重写其抽象方法,除非它也是抽象类
@Override
public void eat() {
System.out.println("狗吃肉!"); //方法的实现,有方法体
}
}
class Cat extends Pet{
@Override
public void eat() {
System.out.println("猫吃鱼!"); //方法的实现
}
}
public class TestDemo6 {
public static void main(String[] args) {
Pet p = new Cat(); //抽象类无法直接创建对象,只能指向非抽象子类
p.eat();
Pet p2 = new Dog();
p2.eat();
}
}
- 只有覆盖了抽象类中所有的抽象方法后,其子类才可以实例化。如果存留未实现的抽象方法则该子类仍为一个抽象类,无法创建对象。
- 抽象类不一定包含抽象方法。
示例:
abstract class Boy{
}
- 抽象类可以有非抽象方法。
示例:
abstract class Girl{
public abstract void sleep();
public void eat(){
System.out.println("女孩喜欢吃零食!");
}
}
- 抽象类拥有构造方法,其存在的意义在于对自身进行初始化,供其子类使用。
- 抽象类一定是个父类,因为抽象类是不断抽取共性需求而来的。
- 抽象类中是可以不定义抽象方法的,此时仅仅是不让该类创建对象,用于某些特殊的设计需要。
- 设计时由具体类抽取出抽象类,而开发阶段应该先定义抽象父类,再根据不同需求由父类定义子类。
12. 普通类和抽象类有哪些区别 ?
- 普通类不能包含抽象方法,抽象类可以包含抽象方法。
- 抽象类不能直接实例化,普通类可以直接实例化。
- 抽象类不能使用 final 修饰,定义为final 的类不能被继承,编译器会报错。
13. 接口和抽象类有什么不同?
- 访问修饰符:接口中的方法默认使用public修饰,抽象类中的方法可以是任意访问修饰符
- 构造函数:接口中不能有,抽象类可以有构造函数
- 抽象类的子类使用extends来继承;接口必须使用implements来实现接口。
- 实现数量:类可以实现很多接口;但是智能继承一个抽象类。
14. Java 中 io 流分为几种?
- 功能来分:输入流(input)、输出流(output)
- 类型来分:字符流和字节流
- 字节流按 8 位传输以字节为单位输入输出数据,字符流按 16 位传输以字符为单位输入输出数据。
15 . BIO、NIO、AIO 三者区别?
- BIO:Block IO同步阻塞式 IO ,就是我们平常使用的传统 IO,他的特点是模式简单使用方便,并发处理能力较低。
- NIO : Non IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 通道(Channel)通讯,实现了多路复用。
- AIO :Asynchronous IO 是NIO 的升级,NIO2,实现了异步费堵塞 IO,异步IO的操作基于时间和回调机制。
16 . Files的常用方法有哪些?
- exists() : 检测文件路径是否存在。
- createFile(): 创建文件、
- createDirectory() : 创建文件夹。
- delete() : 删除一个文件或目录。
- copy():复制文件。
- move():移动文件。
- size():查看文件个数。
- read():读取文件。
- write():写入文件。