牛客网专项练习之《Java基础》错题集1
1、请阅读如下代码
class Foo {
final int i;
int j;
public void doSomething() {
System.out.println(++j + i);
}
}
输出为:不能执行,因为编译错误
解析:
final使用前必须初始化,且 final变量的初始化只有三种方式: 声明时初始化 ,或者构造函数中初始化,或者在代码块中初始化,不能在普通方法中对final进行使用前的初始化
-
2、When is the text “Hi there” displayed?
public class StaticTest { static { System.out.println("Hi there"); } public void print() { System.out.println("Hello"); } public static void main(String args[]) { StaticTest st1 = new StaticTest(); st1.print(); StaticTest st2 = new StaticTest(); st2.print(); } }
答案:
Once when the class is loaded into the Java virtual machine.
被static修饰的语句或者变量有如下特点:
随着类的加载而加载
优先于对象存在
被所有对象所共享
可以直接被类名所调用
使用注意:
静态方法只能访问静态成员
静态方法中不可以写this,super关键字
主函数是静态的
3、关于static说法不正确的是( )
A. 可以直接用类名来访问类中静态方法(public权限)
B. 静态块仅在类加载时执行一次
C. static方法中不能有用this调用的方法
D. 不可以用对象名来访问类中的静态方法(public权限)
正确答案:D
解析:选D
A、静态方法属于类本身,可以使用类名调用。
B、静态块只执行一次。
C、static块和方法不能出现this和super
D、可以的,实例对象也可以调用静态方法。
4、如果int x=20, y=5,则语句System.out.println(x+y +""+(x+y)+y);
的输出结果是()
A. 2530
B. 55
C. 2052055
D. 25255
解析:
不论有什么运算,小括号的优先级都是最高的,先计算小括号中的运算,得到
x+y +""+25+y
任何字符与字符串相加都是字符串,但是是有顺序的,字符串前面的按原来的格式相加,字符串后面的都按字符串相加,得到
25+“”+25+5
上面的结果按字符串相加得到
25255
5、关于Java语言中的final关键字的使用,下列说法正确的是()
A. 在使用final关键字定义的方法里面必须使用final关键字定义变量。
B. 使用final关键字定义变量,必须在变量定义的同时给定变量的具体数值,完成变量初始化。
C. final关键字可以用来修饰方法,表明此方法不可以被子类重写。
D. 使用final关键字定义变量,必须同时使用static关键字。
解析:
A 选项在 final 定义的方法里,不是必须要用 final 定义变量。
B final 定义的变量,可以在不是必须要在定义的同时完成初始化,也可以在构造方法中完成初始化。
C 正确,final修饰方法,不能被子类重写,但是可以被重载。
D final 定义变量,可以用 static 也可以不用。
6、请看如下代码:
public class IfTest{
public static void main(String[]args){
int x=3;
int y=1;
if(x=y)
System.out.println("Not equal");
else
System.out.println("Equal");
}
}
请问:输出的结果为?
答案:An error at line 5 causes compilation to fall.
这个题考查两个知识点。
1、Java中,赋值是有返回值的 ,赋什么值,就返回什么值。比如这题,x = y,返回y的值,所以括号里的值是1。
2、Java跟C的区别,C中赋值后会与0进行比较,如果大于0,就认为是true;而Java不会与0比较,而是直接把赋值后的结果放入括号。
7、@SuppressWarnings(“deprecation”)
的功能是什么?
A. 屏蔽不赞同使用的类和方法的警告
B. 屏蔽在强制类型转换的时候编译器给出的警告
C. 关闭所有警告信息
D. 当在可序列化的类上缺少serialVersionUID定义的警告
正确答案:屏蔽不赞同使用的类和方法的警告
解析:
Java三大注解分别是
@Override
@Deprecated
@Suppresswarnings
@Override
注解表名子类中覆盖了超类中的某个方法,如果写错了覆盖形式,编译器会报错
@Deprecated
表明不希望别人在以后使用这个类,方法,变量等等
@Suppresswarnings
达到抑制编译器产生警告的目的,但是不建议使用,因为后期编码人员看不懂编译器提示的警告,不能更好的选择更好的类去完成任务
8、如何获取ServletContext
设置的参数值?
A. context.getParameter()
B. context.getInitParameter()
C. context.getAttribute()
D. context.getRequestDispatcher()
解析:
getParameter()
是获取POST/GET传递的参数值;getInitParameter()
获取Tomcat
的server.xml
中设置Context
的初始化参数getAttribute()
是获取对象容器中的数据值;getRequestDispatcher()
是请求转发。
9、 在Java中,对于不再使用的内存资源,如调用完成的方法,“垃圾回收器”会自动将其释放。( )
正确答案:错
解析:方法调用时,会创建栈帧在栈中,调用完是程序自动出栈释放,而不是
gc
释放
拓展知识:
JVM
内存可简单分为三个区:1、堆区(heap):用于存放所有对象,是线程共享的(注:数组也属于对象)
2、栈区(stack):用于存放基本数据类型的数据和对象的引用,是线程私有的(分为:虚拟机栈和本地方法栈)
3、方法区(method):用于存放类信息、常量、静态变量、编译后的字节码等,是线程共享的(也被称为非堆,即 None-Heap)
Java 的垃圾回收器
(GC)
主要针对堆区
10、请看如下代码:
class Base
{
public void method()
{
System.out.println("Base");
}
}
class Son extends Base
{
public void method()
{
System.out.println("Son");
}
public void methodB()
{
System.out.println("SonB");
}
}
public class Test01
{
public static void main(String[] args)
{
Base base = new Son();
base.method();
base.methodB();
}
}
问这个程序的输出结果?
正确答案:编译不通过
解析:
Base base = new Son();
这句new 了一个派生类,赋值给基类,所以下面的操作编译器认为base对象就是Base类型的
Base类中不存在
methodB()
方法,所以编译不通过
Base base=new Son();
是多态的表示形式。父类对象调用了子类创建了Son
对象。
base
调用的method()
方法就是调用了子类重写的method()
方法。而此时base还是属于Base对象,base调用
methodB()
时Base对象里没有这个方法,所以编译不通过。要想调用的话需要先通过
Son son=(Son)base;
强制转换,然后用son.methodB()
调用就可以了。
11、 下面关于变量及其范围的陈述哪些是不正确的()
A. 实例变量是类的成员变量
B. 实例变量用关键字static声明
C. 在方法中定义的局部变量在该方法被执行时创建
D. 局部变量在使用前必须被初始化
解析:
A.类的成员变量包括实例变量和类变量(静态变量),成员方法包括实例方法和类方法(静态方法)。 A正确
B.类变量(静态变量)用关键字static声明,B错误
C.方法中的局部变量在****方法被调用加载时开始入栈时创建,方法入栈创建栈帧包括局部变量表操作数栈,局部变量表存放局部变量,并非在执行该方法时被创建,C错误
D.局部变量被使用前必须初始化,否则程序报错。D正确
12、以下程序执行后,错误的结果是()
public class Test {
private String name = "abc";
public static void main(String[] args) {
Test test = new Test();
Test testB = new Test();
String result = test.equals(testB) + ",";
result += test.name.equals(testB.name) + ",";
result += test.name == testB.name;
System.out.println(result);
}
}
答案:
true,true,true
true,false,false
false,true,false
解析:
1、首先应该注意到作为成员变量的name
是使用字面量直接赋值的( privateString name ="abc"; )
这种赋值的执行过程是先看字符串常量池中有没有value
数组为 [‘a’, ‘b’, ‘c’] 的 String 对象,如果没有的话就创建一个,有的话就拿到他的一个引用。2、name 没有被static 修饰,所以每实例化一个对象都会执行
private String name ="abc";
第一次执行的时候发现字符串常量池没有 value 数组为 [‘a’, ‘b’, ‘c’]的String 对象,所以创建一个,拿到他的一个引用,但是第二次的时候发现已经有了这样的对象了, 所以只是拿到这个拿到这个对象的一个引用而已。3、执行
test.name == testB.name;
的时候比较的是两个name
指向的内存是不是同一个(比较引用本身没有意义),所以test.name == testB.name;
的结果是rue
。