目录
1、IO:
(1)Java IO体系中,通常情况下以下哪一个类可用来读取文件且产生的系统调用可能是最少的?
A RandomAccessFile
B FileInputStream
C BufferedReader
D InputStreamReader
答案:C
BufferedReader类提供了缓存机制,可以一次读取多个字符,减少了对底层系统资源的访问次数。因此,相比其他三个选项,使用BufferedReader可能会产生最少的系统调用,从而提高文件读取的效率。
(2)在Java的IO操作中,( )方法可以直接将缓冲中的数据立即发送到网络中?
答案:flush()
flush()方法:flush()方法是Java IO中用于将缓冲区数据写出的方法。对于带缓冲的输出流类,例如PrintWriter、BufferedOutputStream等,在缓冲区数据未达到某个阈值时不会立刻写出到输出流,而是缓存起来,等到达到一定的大小或者手动调用flush()方法时才会将数据写出。flush()方法可以强制将缓冲区中的数据全部写出,在一些场合下比如需要及时输出数据以便及时处理等,这个方法是非常有用的。
2、异常处理相关
(1)关于finally的使用
public class TryDemo {
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
try {
return 1;
} catch (Exception e) {
return 2; }
finally {
System.out.print("3"); }
}
}
解析:应当输出31
因为finally无论如何都要输出,在程序运行到return 1的时候,不能直接return,而要先执行这个finally,再return1.
(2)异常捕获
需要显式捕获或声明的异常主要是编译时异常(checked exception),而不是运行时异常(runtime exception)。
常见的运行时异常如下:
NullPointerException(空指针异常):当尝试访问一个空对象的成员变量或调用空对象的方法时抛出。
ArrayIndexOutOfBoundsException(数组越界异常):当尝试访问数组中不存在的索引位置时抛出。
IllegalArgumentException(非法参数异常):当方法接收到一个非法或不合适的参数时抛出。
IllegalStateException(非法状态异常):当对象的状态与操作不兼容时抛出,例如在对象未正确初始化之前调用其方法。
ArithmeticException(算术异常):当出现数学运算错误时抛出,例如除以零(0)。
ClassCastException(类转换异常):当试图将一个对象强制转换为不是其实际类型的子类时抛出。
UnsupportedOperationException(不支持的操作异常):当调用不支持的方法或操作时抛出,例如对只读集合进行修改操作。
ConcurrentModificationException(并发修改异常):当在迭代过程中对集合进行结构性修改(增加、删除元素)时抛出。
3、hashmap:
以下关于HashMap的说法正确的是() ?
A HashMap类的key可以重复
B HashMap类的key可以为null
C HashMap类的value不可以为null值
D HashMap类的value可以包含null值,并且只能有1个
正确答案:B;解析:
hashmap改写hashcode函数,使key为null空时key值置为0,null作为key只能有有一个,因为如果key值一样会覆盖value,null作为value可以有多个
hashtable不允许key为null是因为会引发空指针异常。
4、字符串类String
4.1
下面这段程序的输出结果( ) ?
public static void main(String[] args) {
String a ="999";
int b =1;
System.out.println(a+b);
}
输出:9991
结论:在Java中,当一个字符串与一个整数相加时,会将整数转换为字符串,然后进行字符串的拼接操作
底层源码分析: 编译器将代码变为如下
从底层看,首先创建了一个空的 StringBuilder
对象 sb
。然后,通过调用 append
方法,将字符串 a
和整数 b
依次添加到 sb
中。最后,通过调用 toString
方法将 StringBuilder
对象转换为一个字符串,并通过 System.out.println
方法进行输出。
public static void main(String[] args) {
String a = "999";
int b = 1;
StringBuilder sb = new StringBuilder();
sb.append(a); // 将字符串 "999" 添加到 StringBuilder 对象
sb.append(b); // 将整数 1 转换为字符串并添加到 StringBuilder 对象
System.out.println(sb.toString()); // 将 StringBuilder 对象转换为字符串并输出
}
4.2 String.valueOf
这个方法的源码底层,会return new String,也就是说创建一个新的对象。因此:
String projectA = "1122"
String projectC = String.valueOf(1122);
这个projectA == projectC 是false
5、关于父类、子类的构造器、super的使用
(1) 理清super与父子类构造器的错综复杂关系
如果子类的构造函数中没有显式调用 super()
,也就是不写super,编译器会在子类的构造函数的第一行自动插入一个无参数的 super()
调用,用于调用父类的无参数构造函数。这是 Java 编译器的默认行为。
也就是说,子类不论是写super();还是不写,都会调用父类无参构造器!
可是如果父类没有无参构造器,只有有参构造器,例如下面代码的Animal父类,此时如果写super(); 或者一个super不写,则报错。因为找不到父类的无参构造器!
class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
// 省略其他代码
}
class Dog extends Animal {
private String breed;
public Dog(String name, String breed) {
//如果写super(); 或者一个super不写,则报错
super(name); // 显式调用父类的有参构造函数
this.breed = breed;
}
// 省略其他代码
}
那我就思考,如果我父类一个构造器都不写呢?
实际上,如果我们不显式定义构造函数,编译器会默认生成一个无参数的构造函数(即默认构造函数),并且该构造函数会调用父类的无参数构造函数(如果有)。因此,父类不必须有构造函数。
但是,一旦我们在父类中显式定义了构造函数(包括有参构造函数和无参构造函数),编译器就不会再自动生成默认构造函数。
也就是说,一旦定义了有参构造器,默认定义的无参构造器就消失了!(自己定义的无参构造器不算),也就是说,此时子类必须显式地调用super,例如上面代码的super(name);。
(2)this
五大作用:
引用当前对象的实例变量:可以使用
this
关键字来引用当前对象的实例变量,以区分局部变量和实例变量的命名冲突。例如,this.name
表示当前对象的name
实例变量。调用当前对象的构造函数:当一个类中存在多个构造函数时,可以使用
this()
来调用同一个类中的其他构造函数。这样可以在一个构造函数中调用另一个构造函数,并且可以传递参数。例如,this(name)
表示调用具有一个参数的构造函数。作为方法的返回值:可以将当前对象作为方法的返回值,使用
return this;
返回当前对象本身。这样可以实现方法链式调用的效果,可以连续调用多个方法。作为方法的参数:可以将当前对象作为方法的参数传递给其他方法,方便在不同的方法之间传递当前对象。
在内部类中使用外部类的实例:当存在内部类时,内部类可以使用
this
来引用外部类的实例。
(3)例题:
java中,下面关于this()和super()说法正确的是?
A. 能够成功调用this(xxx,xxx),则类不能有无参数构造函数
B. 在构造方法内super()必须放第一行,this()不需要
C. 父类没有无参数构造函数时,则在子类构造函数中必须显示调用super
D. super()属于类级静态方法,而this()属于对象方法
答案:C
选项 A 不正确,类可以同时拥有有参和无参构造函数;
选项 B 不正确,this()
和 super()
都需要在构造方法的第一行;
选项C见上文解析,显然正确。
选项 D 不正确,super()
和 this()
都属于对象级方法,不属于类级静态方法。
以下语句中关于Java构造方法的说法错误的是
A.构造方法的作用是为创建对象进行初始化工作,比如给成员变量赋值
B.一个Java类可以没有构造方法,也可以提供1个或多个构造方法
C.构造方法与类同名,不能书写返回值类型
D.构造方法的第一条语句如果是super(),则可以省略,该语句作用是调用父类无参数的构造方法
答案:B
java中就算一个构造器不写,编译器也会默认造一个无参构造器!因此B不对
6、interface接口的定义
概念:
接口使用 interface
关键字定义,只能包含抽象方法和常量:
接口内的字段(常量)类型都必须是public static final的。Java8开始,可以省略,直接定义常量。如int a = 1;
在java8新特性中,可以定义静态方法和默认方法。
在interface定义中以下哪条是正确的?
A.public double methodA(){};
B.Object methodB(Integer x);
C.String constant;
D.static void MethodB(String a);
解析:
A.
public double methodA(){};
这个选项不正确。在接口定义中,方法没有具体的实现,因此不能包含花括号{}
。C.
String constant;
这个选项也不正确。在接口定义中,只能包含方法的声明,而不能包含非常量的变量声明。D.
static void MethodB(String a);
这个选项也不正确。在接口定义中,方法默认是公共抽象方法,不允许使用static
关键字修饰方法。
7、 ||、&&、|、&的使用
核心理论:
单个 | 和 &,无论条件成立,都会进行两边的运算
|| 和 &&,当左边的式子已经满足运算条件后,就不会进行右边的运算。
例题:
根据下面的代码 String s = null;会抛出NullPointerException异常的有()
A. if( (s!=null) & (s.length()>0) )
B. if( (s==null) | (s.length()==0) )
C. if( (s!=null) || (s.length()>0) )
D. if( (s==null) && (s.length()==0) )
解析:首先要明白,s=null, 调用s.length时就会报异常。
根据上面的核心理论 , AB肯定会报异常。
C.左边为false,因为是或,所以仍不能判断结果,要看右边,所以报异常。 D.同理
8、java运算符的优先级
速记:
赋值、逻辑判断优先级是最垃圾的,
然后是移位、加减乘除这些运算,
然后剩下的最强。