java笔试——错题集1

这篇博客讨论了Java编程中的常见错误,包括null与静态方法的调用、同步问题、构造方法、泛型、方法重写和重载、抽象类与接口、集合与异常处理、线程操作和类型转换等。通过对这些知识点的深入分析,帮助读者理解和避免在笔试中常见的错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java基础&纠错
1.知识点:null,静态(静态方法也叫类方法)
public class TestClass {
private static void testMethod(){
System.out.println(“testMethod”);
}
public static void main(String[] args) {
((TestClass)null).testMethod();
}
}
//编译正确,输出testMethod

A.null可以被强制类型转换成任意的类型(TestClass)null,这里被转成了一个类,所以可以通过类名调用静态方

法。

package NowCoder;
class Test {
public static void hello() {
System.out.println(“hello”);
}
}
public class MyApplication {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test=null;
test.hello();
}
}
//编译正确,能正确运行

B.值得一说的是这个空指针问题,如果出现空指针必须去引用堆对象才会有空指针,在这个地方hello()是直接通

过类名调用的静态方法,根本不存在空指针问题
C.另外值得一提的是Test test = null;这句,可以先把他理解成,在栈中开辟空间给了Test test 然后这个所指

向的地址值为空吧,所以这个类是进行了初始化的,可以使用其中的静态方法,静态变量。
D.静态要注意一点,无法在静态上下文引用非静态变量,所以直接调用方法的时候,要注意要么都是静态,要么都

是非静态。不然就要通过创建对象,实例化调用方法

2.知识点:同步
下面关于java的一些细节问题,描述错误的是?
a.构造方法不需要同步化
b.一个子类不可以覆盖掉父类的同步方法

A.构造方法每次都是创建新的对象,不存在多个线程同时读写同一对象中属性的问题,所以不需要同步;
B.如果父类中的某个方法是用了synchronized关键字,而子类中也覆盖这一方法,那默认情况下子类的这个方法是

不同步的,必须显示的在子类的这个方法中加上synchronized关键字才可;当然也可以在子类中调用父类中相应的

方法,这样虽然子类中的方法并不是同步的,但子类调用了父类的同步方法,也就相当于子类方法也同步了

3.知识点:构造方法,方法和类名
下面说法正确的有
a.constructor必须与class同名,但是方法不能与class同名

A.方法可以与类同名,和构造方法的唯一区别就是,构造方法是没有返回值的,构造方法可以由任意访问修饰符修

饰访问,如public,protected,private,但是不能由static,finally等修饰符修饰。

4.知识点:泛型数据
在开发中使用泛型数据取代非泛型数据(比如用ArrayList取代ArrayList),程序运行时的性能会更好


错误

A.泛型仅仅是java语法的语法糖,它不会影响java虚拟机生成汇编代码,在编译阶段,虚拟机就会把泛型的类型还

原成没有泛型的代码,顶多编译速度稍微曼一些,但是执行的时候,速度是完全没有区别的

5.知识点:方法重写和方法重载

A.方法重载:同一个类下,同名方法的参数的类型、顺序、个数不同。和返回值类型无关,返回值类型可以相同也

可以不同,当同一个类中方法同名同参数类型顺序和个数,只有返回值不同的时候,编译报错。

class A{
public A foo(){return this;}
}
class B extends A{
public A foo(){
return this;
}
}
class C extends B

{
_

}
下面哪句可以放到横线位置,使程序正确编译运行?
a.public void foo(){}
b.public int foo(){return 1;}
c.public A foo(B b){return b;}
d.public A foo(){return A;}
答案是c

B.子类重写父类方法要遵循”两同两小一大原则”
1)两同:方法名相同,形参列表完全相同
2)两小:子类方法的返回值类型应该比父类方法的返回值类型更小或者相等;子类方法抛出的异常类应该比父类

方法抛出的异常类更小或者相等。(这里要注意,返回值类型的更大更小,是对于同一类型而言的,也就是说,返

回值的类型需要有继承关系次啊会去考虑大小这个概念,类型不同会报错。即使父类返回double,子类返回int也

不行)
3)一大:子类方法的访问权限应该比父类方法的访问权限更大,或者相等

6.知识点:抽象类和接口

A.抽象类:

1)抽象类有构造方法(不给出就是默认的无参),但是不能创建对象实例化。
2)抽象类中可以存在普通属性,静态属性,普通方法和静态方法
3)抽象类中可以没有抽象方法,只有普通方法,也可以是抽象类;但是只要有抽象方法的类就一定是抽象类
4)抽象类中的抽象方法是一定要被子类实现(重写的),所以抽象方法不可以被private,static,synchronized,native修饰,可以说这就是其设计的目的,如果子类没有重写抽象类

中抽象方法,那么子类也必须是一个抽象类
5)抽象类类名的修饰符必须要有abstract,访问修饰符既可以是public也可以是默认修饰符

B.接口:

1)接口名的修饰符默认是abstract(默认是隐藏的,所以可以加上去),访问修饰符既可以是public也可以是默认

修饰符
2)接口中只有常量,因为在接口中成员变量都被public static final默认修饰
3)接口没有构造方法,也不能被创建对象实例化
4)接口中只有方法的声明,没有方法体
5)接口中的方法都被public abstract默认修饰
6)接口可以多实现,即一个类可以实现多个接口
7)接口中的所有方法实现类必须全部重写,如果实现类不能实现接口中的所有方法,那么这个类必须被定义为抽

象类
8)Jdk1.8的新特性接口可以有静态方法,默认方法了,也就是说可以有static void method(){};静态方法和

default void method(){}默认方法了 ,需要注意的是static,default,abstract,三个修饰符对一个方法

只能三选一(都被public默认修饰),被static,default修饰时候{}不可以省略,并且接口的实现类可以重写这

个方法,也可以不重写这个方法,但是如果被abstract修饰,是一个抽象方法,那还必须符合之前的定义

7.知识点:ArrayList,LinkList,instanceof

public static void main(String args[]) {
List Listlist1 = new ArrayList();
Listlist1.add(0);
List Listlist2 = Listlist1;
System.out.println(Listlist1.get(0) instanceof Integer);
System.out.println(Listlist2.get(0) instanceof Integer);
}
//输出结果:true true

A.collection类型的集合(ArrayList,LinkList)只能装入对象类型的数据,该题中装入了0,是一个基本类型,但

是在jdk5以后提供了自动装箱和自动拆箱,所以int类型就自动装箱成了Interger类型,能够正常的编译
B.instanceof是java中的关键字,用于判断一个对象是否属于某个特定类的实例,并返回boolean类型的返回值,

显然这两个都是Integer类型的值

8.知识点:异常小分类

A.checked exception:指的是编译时异常,该类异常是本函数必须处理的,用try和catch处理,或者用throws抛

出异常,然后交给调用者去处理
B.Runtime exception:指的是运行时异常,该类异常不是本函数必须处理的,当然也可以处理

9.知识点:Thread.sleep(),Object.wait()

A.thread:线程;interrupt 中断;Thread.sleep()和Object.wait()都可以抛出InterruptedException(中断

异常)这个异常是不能被忽略的,属于checked exception(检测异常),而lllegalArgumentException(非法运

算)属于Runtim exception
10.知识点:try,catch,finally

1.public abstract class Test {
public static void main(String[] args) {
System.out.println(beforeFinally());
}

public static int beforeFinally(){
    int a = 0;
    try{
        a = 1;
        return a;
    }finally{
        a = 2;
    }
}

}
/**output:
1
*/

2.public abstract class Test {
public static void main(String[] args) {
System.out.println(beforeFinally());
}

public static int beforeFinally(){
    int a = 0;
    try{
        a = 1;
        return a;
    }finally{
        a = 2;
        return a;
    }
}

}
/**output:
2
*/

A.Code1执行流程:当程序执行到try{}语句中的return方法时,会做这么一件事,将要返回的结果储存到一个临

时栈中,然后程序不会立即返回,而是去执行finally{}中的程序,在执行a = 2时,程序仅仅是覆盖了a的值,但

是不会去更新临时栈中要返回的值,执行完之后,就会通知主程序”finally{}程序执行完毕,可以请求返回了”

,这时就会将临时栈中的值取出来返回,所以输出:1
B.Code2中,finally{}里也有一个return,那么在执行这个return时,就会更新临时栈中的值,同样在执行完

finally{}的程序后,会通知主程序请求返回,这时将临时栈中的值取出来,输出:2
C. finally语句在try或catch中的return语句执行之后,返回值返回之前执行且finally里的修改语句不能影响

try或catch中 return已经确定的返回值,若finally里也有return语句则覆盖try或catch中的return语句直接返

回。
D..多个return是按顺序执行的的,多个return执行了一个后,后面的return就不会执行了。(不考虑finally中有

return中的情况)
E.finally{}中return必须在输出语句之后,否则会报错
F.最后其实可以同样的将finally中的return分成基本数据类型和引用数据类型,即finally中的return对基本数

据类型的返回不会有任何影响,但是对于引用的数据类型,会产生影响,这和数组等的参数传递问题是一脉相承的

3.public class Test{
public int add(int a,int b){
try {
return a+b;
}
catch (Exception e) {
System.out.println(“catch语句块”);
}
finally{
System.out.println(“finally语句块”);
}
return 0;
}
public static void main(String argv[]){
Test test =new Test();
System.out.println(“和是:”+test.add(9, 34));
}
}
//输出结果:
//finally语句块
//和是:43

G. 这里先输出finally语句块的原因是,要考虑到字符串拼接是一个整体,所以是先要执行test.add(9,34),得到

结果后再输出,但是这里执行test.add(9,34)的时候,需要执行finally{},输出”finally语句块”

11.封装类,Boolean

Boolean flag = false;
if (flag = true)
{
System.out.println(“true”);
}
else
{
System.out.println(“false”);
}
//编译成功输出:true

A.Boolean修饰的变量为包装类型(包装类对象),初始值为false,进行赋值操作的时候会调用

Boolean.valueOf(boolean b)方法自动拆箱为基本数据类型,因此

11.知识点——类型转换
byte b1=1,b2=2,b3,b6,b8;
final byte b4=4,b5=6,b7;
b3=(b1+b2); /语句1/
b6=b4+b5; /语句2/
b8=(b1+b4); /语句3/
b7=(b2+b5); /语句4/
System.out.println(b3+b6);
下列代码中存在编译错误的是?

1.Java表达式(千万注意,只有出现表达式,才会考虑类型转换的问题,如果右边是值,就是赋值问题,比如右边是两个final型的变量相加,其实就是两个常数相加然后赋值给左边,但是只要有一个是变量,就要考虑类型转换的问题,整数默认为int类型,小数默认为double类型)转型规则由低到高转换:
1、所有的byte,short,char型的值将被提升为int型;
2、如果有一个操作数是long型,计算结果是long型;

3、如果有一个操作数是float型,计算结果是float型;

4、如果有一个操作数是double型,计算结果是double型;
5、被fianl修饰的变量不会自动改变类型,当2个final修饰相操作时,结果会根据左边变量的类型而转化。
————–解析————–
语句1错误:b3=(b1+b2);自动转为int,所以正确写法为b3=(byte)(b1+b2);或者将b3定义为int;
语句2正确:b6=b4+b5;b4、b5为final类型,不会自动提升,所以和的类型视左边变量类型而定,即b6可以是任意数值类型;
语句3错误:b8=(b1+b4);虽然b4不会自动提升,但b1仍会自动提升,所以结果需要强转,b8=(byte)(b1+b4);
语句4错误:b7=(b2+b5); 同上。同时注意b7是final修饰,即只可赋值一次,便不可再改变。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值