1.(单选题)程序执行的结果是:()。
public class Point{
int y = 7;
public void step(int y) {
y += y;
System.out.println(y);
}
public static void main(String[] args) {
Point p = new Point();
p.step(10);
}
}
A.14
B.20
C.10
D.17
【正确答案】B。
【答案解析】解析:本题考查成员变量和局部变量的区别。这个用法是一个反面案例。 本题中, step方法中的代码行 “ y += y;”其中的两个y都是局部变量,即step方法的形式参数y。如果要引用成员变量y那么应该是this.y。 当实参10传递给step方法的形参y时,根据之前的解释,“ y += y;”中的两个y表示的是局部变量y,计算后,y的值为20。
2.(单选题)程序的执行结果是:()。
public class Question {
private int num;
public static void main(String [] args){
Question q = new Question();
q.num=13;
update(q);
System.out.println(q.num);
}
public static void update(Question q){
q.num=9;
}
}
A.13
B.9
C.0
D.4
**【正确答案】B。
【答案解析】**解析:本题考查的是Java的方法参数传递。在Java中方法参数传递只有值传递,其特点如下: 1)基本数据类型传递的是值本身。 2)引用数据类型传递也是引用的值,是对象的地址,而不是对象本身。 本题运行过程如下: 1.执行Question q = new Question();这句代码,在堆内存中为Question类的对象,分配内存空间并初始化成员变量num;在栈内存中分配变量q的值是堆中Question类型对象的首地址。 2.执行q.num=13;将q引用的堆内存中的对象的成员变量num的值改为13。 3.调用update方法,将main方法中q的值(对象首地址)赋值给方法形式参数q,此时,方法形式参数q和main方法中q指向了同一对象。 4.在update方法找中,改变形式参数q引用的对象的属性num的值为9。 5.由于main方法中的引用q和update方法形参q指向了相同对象,所以在main方法中输出q.num的值和方法形式参数q引用的对象的属性num值应该是一样的,都是9。
3.(单选题)程序执行的结果是:()。
public class Answer {
public static void main(String[] args) {
int score = 20;
Answer ans= new Answer();
ans.add(score);
System.out.println(" main: score = " + score);
}
void add(int score) {
System.out.println(" add: score=" + score++);
}
}
A.
add: score=21
main: score = 21
B.
add: score=20
main: score = 21
C.
add: score=21
main: score = 20
D.
add: score=20
main: score = 20
【正确答案】D。
【答案解析】解析:本题考查的是Java的方法参数传递。在Java中方法参数传递只有值传递,其特点如下: 1)基本数据类型传递的是值本身。 2)引用数据类型传递也是引用的值,是对象的地址,而不是对象本身。 本题中,首先要明白main方法中的局部变量score,和add方法的形参score在栈内存中是两个变量,当调用add方法时,是把main方法中局部变量score的值20赋值给add方法的形式参数score,所以当形参score在add方法中发生变化时不会影响到main方法中局部变量score的值。 本题运行过程如下: 1.从main方法的第一行开始,定义并初始化局部变量score。 2.实例化Answer类的对象ans,调用add方法,将main方法中的score的值赋值给形参score,此时,形参score的值为20。 3.计算表达式score++的值。计算后,score++表达式的值为20,score的值变为21。此处输出的是score++表达式的值,该值为20。 4.由于形式参数score的改变不会影响main方法中score的值,故main方法中输出score仍然为20。
4.(单选题)关于下列代码说法正确的是:()。
public class Storm {
public void find() {
}
public String find() {
return “find”;
}
public double find(int x) {
return 2.0;
}
}
A.无编译错误
B.代码 public String find() { 行,出现编译错误
C.代码 public double find(int x) {行,出现编译错误
D.代码 return “find”;行处出现编译错误
【正确答案】B。
**【答案解析】**解析:本题考查方法重载。 在Java语言中,允许多个方法的名称相同,但参数列表不同,称之为方法的重载(overload)。编译器在编译时会根据其参数的不同,绑定到不同的方法。在这里需要强调的是和返回值无关。 本题中,方法 public void find() {}和 方法public String find() {}参数列表相同,不符合方法重载的定义,会在两个方法声明处出现编译错误。
5.(单选题)请看下列代码:
class ClassA {}
class ClassB extends ClassA {}
class ClassC extends ClassA {}
public class Test{
public static void main(String[] args) {
ClassA p0 = new ClassA();
ClassB p1 = new ClassB();
ClassC p2 = new ClassC();
ClassA p3 = new ClassB();
ClassA p4 = new ClassC();
<插入代码>
}
}
下列选项中放置在<插入代码>处,使程序编译正确的是:()
A.p0 = p1;
B.p1 =p2;
C.p2 = p4;
D.p2 = (ClassC)p1;
**【正确答案】A。
【答案解析】**解析:本题考查向上造型。一个类的对象可以向上造型的类型有: a.父类的类型 b.其实现的接口类型 Java编译器根据类型检查调用方法是否匹配。 本题中, A选项,ClassB是ClassA的子类,p0是ClassA的对象,p1是ClassB的对象,p0=p1,符合一个子类的对象可以向上造型为父类的类型,故A选项正确。 B选项,p1是ClassB的对象,p2是ClassC的对象,ClassB和ClassC不存在继承关系,p1=p2;不成立,故选项B不正确。 C选项,p2是ClassC的对象,p4的类型是ClassA,p4指向的实例是ClassC的对象,ClassC继承自ClassA,故p4=p2成立,符合一个子类的对象可以向上造型为父类的类型,但是返回来p2=p4;则不成立。 D选项,p1是ClassB的对象,p2是ClassC的对象,ClassB和ClassC不存在继承关系,故p2 = (ClassC)p1;不成立,D选项不正确。
6.(单选题)请看下列代码编译和运行的结果是:()。
public class Teacher {
private String name=“sun”;
public static void main(String[] args) {
Teacher[] teachers=new Teacher[2];
System.out.println(teachers[0].name);
System.out.println(teachers.length);
}
}
A.sun 2
B.null 2
C.null 1
D.运行时抛出NullPointerException异常
【正确答案】D
**【答案解析】**解析:本题考查引用类型数组。 所谓引用类型数组,是数组的元素不是基本类型,而是引用类型。引用类型数组的初始化和基本类型数组的初始化方式一样,只不过元素是引用而已。但需要注意: 基本类型数组元素的默认初始值为具体值(例如,int类型数组的元素默认初始值为0);而引用数组创建后,其元素的默认值为null, 不创建元素对象。 本题中,Teacher类型作为数组的元素的类型,数组teachers创建后,数组teachers中的每一个元素的值为null,即数组元素为{null,null},例如题目中的teachers[0]这个数组元素的默认值为null,通过它去访问属性或方法会抛出NullPointerException异常。
7.(单选题)下列代码编译和运行的结果是:()。
class Person {
String name = " ";
public Person(String name) {
this.name = name;
}
}
class Employee extends Person {
String empNO = “0000”;
public Employee(String empNO) {
this.empNO = empNO;
}
}
public class EmployeeTest {
public static void main(String[] args) {
Employee e = new Employee(“1109”);
System.out.println(e.empNO);
}
}
A.输出:0000
B.输出:1109
C.代码public Employee(String empNO) {行,出现编译错误
D.抛出运行时异常
【正确答案】C
**【答案解析】**解析:本题考查继承中的构造方法。 子类的构造方法中必须通过super关键字调用父类的构造方法,这样可以妥善的初始化继承自父类的成员变量。如果子类的构造方法中没有调用父类的构造方法,Java编译器会自动的加入对父类无参构造方法的调用(如果该父类没有无参的构造方法,会有编译错误)。 本题中,父类Person没有提供无参数的构造方法,因此在代码public Employee(String empNO) {行,出现编译错误。
8.(单选题)下列代码编译和运行的结果是:()。
class A {
public void start() {
System.out.println(“A Start”);
}
}
public class B extends A {
public void start() {
System.out.println(“B Start”);
}
public static void main(String[] args) {
((A) new B()).start();
}
}
A.输出:A Start
B.输出:B Start
C.输出:A Start
B Start
D.编译错误
【正确答案】B
**【答案解析】**解析:本题考查方法的重写。 子类可以重写(覆盖)继承自父类的方法,即方法名和参数列表与父类的方法相同;子类利用重写修改父类的方法。当子类对象的重写方法被调用时(无论是通过子类的引用调用还是通过父类的引用调用),运行的是子类的重写修改后的版本。
9.(多选题)请看下列代码:
在<插入代码>处填入选项中的代码,使T类没有编译错误的是:()。
public class Tetromino {
protected int move(int x) {
return 0;
}
}
class T extends Tetromino {
<插入代码>
}
A.public int move(int x) { return 0; }
B.private int move(int x) { return 0; }
C.private int move(long x) { return 0; }
D.protected long move(int x) { return 0; }
【正确答案】A,C
**【答案解析】**解析:本题考查方法的重写和重载语法。 子类可以重写(覆盖)父类的方法。方法的重写要遵循“两同两小一大”规则,“两同”即方法名相同,形参列表相同;“两小”指的是子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等;“一大”指的是子类方法的访问权限应比父类方法的访问范围更大或相等。 在Java语言中,允许多个方法的名称相同,但参数列表不同,称之为方法的重载。 选项A,符合重写的定义,A选项正确。 选项B,不符合重写也不符合重载的语法,B选项错误。 选项C,符合重载的语法,子类T继承父类Tetromino的 protected int move(int x) 方法,与C选择属于重载,C选择正确。 选项D,不符合重写也不符合重载的语法,D选项错误。
10.(多选题)下列关于JVM的内存结构描述正确的是:()。
A.类的各种信息在堆中保存
B.栈用于存放程序运行过程当中所有的局部变量
C.堆一般用于存储使用new关键字创建的对象
D.类是JVM的内存结构
【正确答案】B,C
**【答案解析】**解析:本题考查JVM的内存结构。 JVM的内存结构有方法区,堆,栈等。其中方法区用于保存类的各种信息;栈用于存放程序运行过程当中所有的局部变量;堆一般用于存储使用new关键字创建的对象。 类属于Java语言中引用类型的一种,不属于JVM的内存结构。
11.(多选题)请看下列代码:
public class Line {
private Point p;
public Line() {
<插入代码>
}
public class Point { }
}
在<插入代码>处,需要创建Point类的对象,下列选项正确的是:()。
A.super.p = new Point();
B.p = super.new Point();
C.p =new Point();
D.p =this.new Point();
**【正确答案】C,D
【答案解析】**解析:考查如何创建成员内部类的对象。 一般情况下,内部类对象会在其所在的外部类对象中创建(构造方法或其他方法);内部类对象中会有一个隐式的引用指向创建它的外部类对象。 成员内部类, 必须使用“外部类的实例.new” 来创建对象。 本题中,在外部类的内部来创建成员内部类的对象可以省略this,即将 “this.new Point()” 省略为 “new Point()”,因此CD选项都正确。
12.题目
public class Test {
public static void main(String[] args) {
Test test = new Test();
test.fun1();
}
public void fun1(){
int i = 2;
Num num = new Num();
num.i = 3;
fun2(num,i);
System.out.print(num.i);
}
public void fun2(Num num, int i){
i = 0;
num.i = 4;
Num num2 = new Num();
num = num2;
System.out.print(num.i + " " + i + " ");
}
}
class Num{
public int i = 1;
}
上述代码的输出结果是?
A.1 0 1
B.1 0 4
C.4 0 3
D.3 2 3
答案与解析
1.相关知识
对象作为参数传递到方法时,传递的是其地址,如果修改其内容,则会将原对象的内容也修改。
对方法形参的修改,不会影响到传递的实参。
2.答案解析
num实例化之后,将成员i的值修改为3
fun2方法传递了num实例和i
之后又修改了i的值为0,num实例的成员i为4
创建了新的num2实例,并且让num指向num2
第一个输出num.i指向的是新的num2实例,因此输出1,i被修改为0,输出0,此时输出为1 0
返回方法1,输出num实例的i,因为在fun2中已经将num实例的i成员修改为了4,因此此时输出为4
最终输出结果为1 0 4,答案选B。
13…(单选题)下列正确的定义数组的选项是( )。
A.int [] arr;
B.int [5] arr;
C.int arr[5];
D.int arr ;
答案: A。我错选成C了,int [ ] arr =new int[5];才正确。
14.(单选题)以下代码执行后的输出结果为:( )
int x= -3;
int y= -10;
System.out.println(y%x);
A.-1
B.2
C.1
D.3
答案:A。常识错误,(-10) /(-3)商为3,余数为-1.被除数 =商*除数+余数。
15.(单选题)下列程序运行结果是(D )。
public class Test {
String str=new String(“tedu”);
char[]ch={‘x’,‘y’,‘z’};
public static void main(String args[]){
Test t = new Test();
t.change(t.str,t.ch);
System.out.print(t.str+" and “);
System.out.print(t.ch);}
public void change(String str,char ch[]){
str=“tarena”;
ch[0]=‘w’;
}
}
A.tedu and xyz
B.tarena and xyz
C.tedu and wyz
D.tarena and wyz
答案:C。我错选成了D。
先看String str=new String(“tedu”);在堆中开辟空间存放String类型内容"tedu”,在栈中开辟地址空间保存地址值str,该地址指向该内容。
再看char[]ch={‘x’,‘y’,‘z’}; 这里需要注意的是char是基本数据类型,数组自带toString()方法,输出ch会直接把数组内容xyz全部输出来。
基本数据类型无论是输出变量名还是对象打.调用都是变量中的内容,而引用数据类型输出变量名是栈中的引用地址,对象打.调用输出的是堆中的内容。
change方法参数列表中,参数都为引用数据类型,传过来的都是地址,新地址str1=原地址str,新地址ch1=原地址ch。方法体中,str1 = tarena,就是把栈中的地址从str变为tarena,指向的堆中空间内容变为一个陌生的空间,所以输出的t.str中内容没有变化,仍为tedu。再看ch[0]=‘w’;因为ch1的地址没变,和ch的地址完全相同,所以指向的堆空间内容都是同一个内容,第一个元素被改为w,所以输出wyz。
16.(单选题)给出以下代码,请问该程序的运行结果是( )。
public abstract class AbstractClass{
public AbstractClass(){
System.out.printIn(“abstract class constructor!”);
}
public void aMethod(){
System.out.printIn(“method in the abstract class”);
}
}
A.代码编译失败,因为抽象类不能有构造器。
B.代码编译失败,因为当类不存在抽象方法时,是不能定义为抽象类的。
C.代码编译成功,并且因为该类实际上不是抽象类,因此可以被实例化。
D.代码编译成功,但不能被实例化。可以被扩展为非抽象类,子类的构造器可以调用抽象父类的构造器。
正确答案:D。我错选为A,我以为抽象类没有构造方法。
抽象类可以有构造方法,但是不能被实例化。接口才不能有构造方法,不能实例化,记混了。
17.(单选题)下列程序输出结果是( )。
class Super {
public static void m1() {
System.out.println(“m1 in Super”); }
public void m2() {
System.out.println(“m2 in Super”); }}
class Sub extends Super {
public static void m1() {
System.out.println(“m1 in Sub”); }
public void m2() {
System.out.println(“m2 in Sub”); }}
public class TestMain {
public static void main(String args[]) {
Super sup = new Sub();
sup.m1();
sup.m2();
Sub sub = (Sub) sup;
sub.m1();
sub.m2(); }}
A.m1 in Sub
m2 in Sub
m1 in Sub
m2 in Sub
B.m1 in Super
m2 in Super
m1 in Sub
m2 in Sub
C.m1 in Sub
m2 in Sub
m1 in Super
m2 in Super
D.m1 in Super
m2 in Sub
m1 in Sub
m2 in Sub
正确答案;D。我错选为B。
先分析一下两个类:
父类Super,静态方法m1,普通方法m2,。
子类Sub继承父类Super,静态方法m1,因为静态方法不能被重写,所以m1为子类Sub独有的静态方法,只是恰巧和父类Super的静态方法m1重名而已。而普通方法m2就是重写的父类方法。
再看main方法:
第一句,向上造型Super sup = new Sub();父类Super类型变量sup中的引用地址指向实例化的Sub类型对象。sup.m1();先分析sup引用实际指向的是子类对象,如果方法被子类重写就会调用子类重写后的方法,但是m1是静态方法不能被重写,所以直接调的是本类Super的m1方法。而sup.m2();实际指向的子类对象调用的是被重写后的普通方法m2。
第二句,向下造型Sub sub = (Sub) sup;把Super类型sup变量保存的引用地址指向的子类对象(向上造型)再赋给子类引用sub,强制转换,没有向上造型就没有向下造型。
sub.m1();子类引用sub指向的子类对象,调用静态方法m1,只能是子类的m1静态方法。
sub.m2();子类引用sub指向的子类对象,调用普通方法也是子类的m2普通方法。
总之,调用静态方法看类型,调用普通方法看对象。
18.(单选题)下面代码输出结果是( )。
int x = 0, y = 0;
do {
if (x % 3 == 0) {
x++;
continue;
}
x++; x//1,2,3,4
y = y + x; y//1,3,6
} while (x < 4);
System.out.println(y);
A.0
B.3
C.5
D.7
正确答案:C。我选的B。
注意0%3为0,continue跳出循环的时候最后还有条件判断。
19.(多选题)请选出属于JDK的组成部分( ABC)。
A.支持JAVA程序运行的一组类库
B.JVM
C.支持JAVA程序开发的一组开发工具
D.一组软件测试工具
正确答案:ABC。注意JVM也是JDK一部分,JDK包括JRE和Java开发命令,JRE又包括JVM和Java类库。
20…(多选题)下列程序中不会出现编译错误的是( )
A.short s1 = 3;
short s2 = 5;
s1 += s2;
B.short s1 = 3;
short s2 = 5;
s1 = s1+s2;
C.short s1 = 3;
short s2 = 5;
s1 = s1 * s2;
D.short s1 = 3;
short s2 = 5;
s1 *= s2 ;
正确答案:AD.。我选的ABCD。
AD中的符合复合赋值表达式自带强转技能,注意BC用的变量名运算,运算结果为int型,不能再赋给short型。
21.(多选题)关于类、对象、引用以下描述正确的是()。
A.Person person = new Person(“张三”);
person是一个对象,是内存中的一块区域,是Person类的一个实例
B.Person person = new Person(“张三”);
person并不是真正的对象,而是指向所创建的对象的引用
C.Person person;
person = new Person(“张三”);
person = new Person(“李四”);
person是引用类型的变量,指向了“张三”和“李四”两个对象
D.Person person;
person = new Person(“张三”);
person = new Person(“李四”);
person是引用类型的变量,最后指向了“李四”这个对象
正确答案:BD。错选为AC。
注意一个地址只能指向一个对象,数组中各个元素的地址也是各自指向各个对象。
22.输出结果是()
public class Super {
int a = 6;
public Super(){
test();
}
public void test(){
System.out.println(a);
}
}
public class Sub extends Super {
int a = 8;
public Sub(){
test();
}
public void test(){
System.out.println(a);
}
}
public static void main(String[] args) {
new Sub();
}
正确答案: 0 8。
这个题考的也就是类的初始化过程。运行过程如下❶→⑮:
public class Super {
int a = 6;// ❸先为a分配内存空间,默认初始化值为0.
public Super() {// ❻父类无参构造
super(); // ❼默认调用Object中的无参构造
// a = 6; ❽默认成员变量在构造方法中这样赋值,此时父类的实例变量a值为6.
test();// ❾调用text()方法,运行期绑定,真实指向的是子类对象,所以调用的是子类重写后的方法
}
public void test() {
System.out.println(a);//
}
}
public class Sub extends Super {
int a = 8;// ❸先为a分配内存空间,默认初始化值为0.
public Sub() {// ❹子类无参构造
super();// ❺默认调用父类Super的无参构造
// a = 8; ⑫默认成员变量在构造方法中这样赋值,此时a已经被赋值为8.
test();// ⑬调用test()方法,真实指向子类对象,调用的为子类test()方法
}
public void test() {// ❿重写后的子类text()方法 ⑭再次被调用,此时a已经被赋值为8.
System.out.println(a); // ⑪此时父类的实例变量a的值为默认值0. ⑮输出a的值8.
}
}
public class Text {
//❶JVM类加载器会先把Super.class、Sub.class、Text.class字节码文件加载进内存
public static void main(String[] args) {// 程序入口→
new Sub();// ❷实例化一个子类对象,在堆内存中为这个对象开辟空间
}
}
23.输出结果是()
public class Demo01 {
public static void main(String[] args) {
int i = 3;
String str = “gbk”;
char[] chs = {‘a’,‘b’,‘c’};
Demo01 demo01 = new Demo01();
demo01.change(i, chs);
//System.out.println(str);
System.out.println(i)
System.out.println(chs);
}
public void change(int i,char[] chs){
i = 12;
chs[0] = ‘k’;
}
正确答案:3 kbc
public class Demo01 {
public static void main(String[] args) {// 程序入口
int i = 3;// ❶局部变量i的值为3,在栈中保存
String str = "gbk";// ❷引用变量str在栈中,内容"gbk"在堆中的常量池中
char[] chs = { 'a', 'b', 'c' };//❸数组引用变量chs在栈中,数组内容在堆中
Demo01 demo01 = new Demo01();// ❹实例化该类的一个对象,对象引用变量在栈中,指向堆中的对象
demo01.change(i, chs);// ❺对象调用chang()方法,按值传递(基本数据类型传数值,引用类型传地址)
System.out.println(str);// ❾输出gbk
System.out.println(i);// ❿输出3
System.out.println(chs);// ⑪输出kbc,这里要注意char数组的唯一特点:自带toString()方法
}
public void change(int i, char[] chs) {//❻把值拷贝一份到方法栈中,i1=i,chs1=chs(指向同一数组).
i = 12;// ❼i1=12,i的值仍然为3.
chs[0] = 'k';// ❽chs1[0]='k',堆中内容改变,chs[0]也为'k'.
}
}
24.输出结果是()
public class ExtendsConstrutorsDemo02 {
public static void main(String[] args) {
new B();
}
}
class A{
A(){
System.out.println(“A构造方法”);
}
}
class C{
C(){
System.out.println(“C构造方法”);
}
}
class B extends A{
private C c = new C();
B(){
System.out.println(“B构造方法”);
}
}
正确答案:A构造方法 C构造方法 B构造方法。
public class Practice24 {
public static void main(String[] args) {// 程序入口
new B();// ❶实例化B类对象
}
}
class A {
A() {
System.out.println("A构造方法");// ❸输出A构造方法
}
}
class C {
C() {
System.out.println("C构造方法");// ❺输出C构造方法
}
}
class B extends A {//
private C c = new C();// ❹↓
B() {
super();// ❷默认调用父类A构造方法
// private C c = new C(); ❹父类构造运行完后,会运行子类中的内容
System.out.println("B构造方法");// ❻输出B构造方法
}
}