当前位置: 首页 > news >正文

java上机测试错题回顾(1)

平时不能摸鱼太多,这样导致到最后不能摸鱼......

看了看日历原来是6.12就结课了,啊哈哈,真没几天准备了,期末月你要来了吗?

1 参数传递,值传递~!

题目

以下代码的输出结果为( )。

public class Pass{static int j = 20;public void amethod(int x){x = x*2;j = j*2;}public static void main(String args[]){int i = 10;Pass p = new Pass();p.amethod(i);p.amethod(i);System.out.println(i+" and "+j);}
}

A. 错误:方法参数与变量不匹配
B. 20 and 40
C. 10 and 40
D. 10 and 20

答案:C        我的错误答案:B

在 Java 中,方法参数传递是值传递。

main方法里定义的int i = 10 ,调用p.amethod(i) 时,只是把i的值(也就是 10 )传递给了方法amethod的参数x 。

amethod方法内部对x进行x = x*2 操作,只是改变了方法内部x的值,并不会影响到main方法里的i ,所以i的值还是 10 。

j是类的静态变量,在amethod方法里执行j = j*2 ,会改变j的值(从 20 变为 40 ) 。所以最终输出是10 and 40,不是20 and 40 。

2 编译出错

题目

编译和运行下列程序会出现什么样的结果( )。

public class Ref {public static void main(String[] args){Ref r = new Ref();r.amethod(r);}public void amethod(Ref r){int i = 99;multi(r);System.out.println(i);}public void multi(Ref r){r.i = r.i * 2;}
}

A. 编译出错
B. 输出: 99
C. 输出: 198
D. 运行出错

解析

  1. 变量作用域分析:在amethod方法中,定义了局部变量int i = 99 ,这个i只在amethod方法内部有效。
  2. multi方法分析multi方法中尝试访问r.i ,但类Ref中并没有定义成员变量i ,这里会导致编译错误,因为无法识别r.i 。

所以答案是 A,编译出错。

3 生成随机整数

题目

要产生 [20,999] 之间的随机整数使用哪个表达式?( )
A. (int)(20+Math.random ()*97)
B. 20+(int)(Math.random ()*980)
C. (int) Math.random ()*999
D. 20+(int) Math.random ()*980

解析

  • 选项 AMath.random()会生成一个大于等于 0.0 且小于 1.0 的随机小数。Math.random()*97得到的随机数范围是大于等于 0.0 且小于 97.0 ,再加上 20 后,范围是大于等于 20.0 且小于 117.0 ,强制类型转换为int后,得到的随机整数范围是 [20, 116] ,不符合 [20, 999] 的要求,所以 A 选项错误。
  • 选项 BMath.random()*980得到的随机数范围是大于等于 0.0 且小于 980.0 ,将其强制转换为int后,范围是 [0, 979] ,再加上 20 ,得到的随机整数范围是 [20, 999] ,符合题目要求,所以 B 选项正确。
  • 选项 CMath.random()强制转换为int后结果为 0 (因为Math.random()生成的数小于 1.0 ),再乘以 999 结果还是 0 ,无法得到 [20, 999] 之间的随机整数,所以 C 选项错误。
  • 选项 D:在 Java 中,(int)Math.random()*980这种写法,先对Math.random()进行强制类型转换为int结果为 0 ,再乘以 980 还是 0 ,加上 20 结果为 20 ,只能得到 20 这一个数,不能得到 [20, 999] 之间的随机整数,所以 D 选项错误。

知识点

  • Math.random()函数:在 Java 中,Math.random()java.lang.Math类中的静态方法,用于生成一个伪随机的 double 类型数,其取值范围是大于等于 0.0 且小于 1.0 ,即 [0.0, 1.0) 。
  • 生成指定范围随机整数的公式:若要生成范围在[min, max]minmax为整数)之间的随机整数,公式为min + (int)(Math.random() * (max - min + 1)) 。在本题中,min = 20max = 999 ,代入公式可得20 + (int)(Math.random() * (999 - 20 + 1)) = 20 + (int)(Math.random() * 980) 。

4 操作符的权限

题目

下面的( )操作符可以使其修饰的变量只能对同包中的类或子类可见
A. private
B. public
C. protected
D. default

答案:C

知识点

  • private:是访问修饰符,被private修饰的变量、方法等,只能在本类内部被访问 ,在类外部以及其他类中都无法访问。
  • public:也是访问修饰符,被public修饰的变量、方法等,具有最大的访问权限,在任何包中的任何类都可以访问。
  • protected:此访问修饰符修饰的变量、方法等,在同包中的类可以访问,不同包中的子类也可以通过继承关系访问 。满足题目中 “同包中的类或子类可见” 的要求。
  • default(默认,无修饰符):当成员变量或方法没有使用任何访问修饰符时,具有包访问权限,即只能在同一个包中的类访问,不同包子类不能访问。

5 继承 

题目提取

给定如下代码,哪个表达是错误的?

class C1 {}
class C2 extends C1 {}
class C3 extends C2 {}
class C4 extends C1 {}C1 c1 = new C1();
C2 c2 = new C2();
C3 c3 = new C3();
C4 c4 = new C4();

A. c1 是 C1 的实例
B. c2 是 C1 的实例
C. c3 是 C1 的实例
D. c4 是 C2 的实例

解析

在 Java 中,涉及到类的继承关系时,存在 “多态” 特性,子类对象可以被视为父类对象 。

  • 选项 Ac1 = new C1() ,c1 明确是通过 C1 类实例化得到的对象,所以 c1 是 C1 的实例,该选项正确。
  • 选项 BC2 类 extends C1,即 C2 是 C1 的子类。根据继承关系,子类对象也是父类的一种特殊形式,所以 c2 这个 C2 的实例也可以被看作是 C1 的实例,该选项正确。
  • 选项 CC3 类继承自 C2,而 C2 又继承自 C1C3 是 C1 的间接子类,c3 这个 C3 的实例同样也可被视为 C1 的实例,该选项正确。
  • 选项 DC4 类继承自 C1,和 C2 没有继承关系,所以 c4 是 C4 和 C1 的实例,但不是 C2 的实例 ,该选项错误。

综上,答案是 D。

6 多态

Java 中的多态性是面向对象编程的重要特性之一,它允许不同类的对象对同一消息作出不同的响应,主要通过以下几种方式体现:

方法重载(静态多态)

  • 定义:在同一个类中,方法名相同,但参数列表(参数个数、参数类型、参数顺序)不同的多个方法。编译器根据方法调用时实际传入的参数来确定调用哪个方法,这是在编译期就确定的,因此也称为静态多态。
  • 示例

java

public class OverloadExample {public int add(int a, int b) {return a + b;}public double add(double a, double b) {return a + b;}
}

这里 add 方法有两个不同的版本,一个处理 int 类型参数,一个处理 double 类型参数,调用时根据传入参数类型决定调用哪个方法。

方法重写(动态多态)

  • 定义:子类对父类中已有的方法进行重新实现。要求方法名、参数列表、返回值类型必须与父类中被重写的方法一致(在 Java 5 之后,返回值类型可以是被重写方法返回值类型的子类,即协变返回类型)。重写体现了运行时多态,程序运行时根据对象实际类型决定调用哪个类的重写方法。
  • 示例
class Animal {public void speak() {System.out.println("Animal makes a sound");}
}class Dog extends Animal {@Overridepublic void speak() {System.out.println("Dog barks");}
}

这里 Dog 类重写了 Animal 类的 speak 方法。当使用父类引用指向子类对象时,调用 speak 方法实际执行的是子类重写后的方法。

多态的实现机制

  • 动态绑定:Java 虚拟机(JVM)在运行时根据对象的实际类型来决定调用哪个类的方法。当通过父类引用调用一个被子类重写的方法时,JVM 会在子类中查找对应的重写方法并调用。
  • 向上转型和向下转型
    • 向上转型:子类对象赋值给父类引用,如 Animal animal = new Dog(); 。向上转型是安全的,因为子类是父类的一种特殊形式,这样可以方便地将子类对象当作父类对象进行统一处理,实现多态调用。
    • 向下转型:将父类引用转换为子类类型,如 Dog dog = (Dog)animal; 。向下转型需要谨慎,因为只有当父类引用实际指向的是子类对象时才是合法的,否则会抛出 ClassCastException 异常。通常需要结合 instanceof 关键字进行类型判断后再转型,如 if (animal instanceof Dog) { Dog dog = (Dog)animal; } 。

多态的优点

  • 提高代码的可维护性和扩展性:当增加新的子类时,只要遵循父类的方法定义,不需要修改调用这些方法的代码,只需要在子类中实现相应方法即可。
  • 增强代码的灵活性:可以用统一的方式处理不同类型的对象,使程序设计更加灵活和通用。

 7 对象声明与多态

题目

有如下程序代码,执行的结果是( )。

java

class Father {int a = 100;int b = 200;public void print() {System.out.println(a + " " + b);}
}
class Child extends Father {int b = 300;int c = 400;public void print() {System.out.println(a + " " + b + " " + c);}public void printExtend() {System.out.println(c);}
}
public class Main {public static void main(String[] a) {Father obj=new Child();System.out.println(obj.a+" "+obj.b);obj.print();}
}

解析

  1. 对象声明与多态
    • Father obj=new Child(); 这行代码创建了一个 Child 类的对象,但是使用 Father 类型的引用变量 obj 来指向它,这是多态的体现。【向上转型~】
  2. 访问成员变量
    • 对于 System.out.println(obj.a+" "+obj.b); ,在 Java 中,当通过父类引用访问成员变量时,访问的是父类中定义的成员变量。所以这里访问的 a 是 Father 类中的 a ,值为 100 ;访问的 b 也是 Father 类中的 b ,值为 200 。因此这行代码输出 100 200 。
  3. 方法重写与动态绑定
    • obj.print(); 这里调用 print 方法,由于 Child 类重写了 Father 类的 print 方法,根据动态绑定机制,在运行时会调用 Child 类中重写后的 print 方法。在 Child 类的 print 方法中,a 仍然使用父类的 a (值为 100 ),b 使用 Child 类中定义的 b (值为 300 ),c 是 Child 类中定义的(值为 400 ),所以这行代码输出 100 300 400 。

综上,程序的输出结果是先输出 100 200 ,然后输出 100 300 400 。

8 构造方法调用顺序 

题目

分析如下代码,正确的选项是( )。

java

public class Test {public static void main(String[] args) {new B();}
}
class A {int i = 7;public A() {setI(20);System.out.println("i from A is " + i);}public void setI(int i) {this.i = 2 * i;}
}
class B extends A {public B() {// System.out.println("i from B is " + i);}@Overridepublic void setI(int i) {this.i = 3 * i;}
}

A. A 的构造方法未被调用。
B. A 的构造方法被调用,并且输出 "i from A is 7"。
C. A 的构造方法被调用,并且输出 "i from A is 40"。
D. A 的构造方法被调用,并且输出 "i from A is 60"。

解析

  1. 构造方法调用顺序:在 Java 中,当创建子类对象时,会先调用父类的构造方法 。这里 new B() 创建 B 类对象,B 继承自 A,所以会先调用 A 的构造方法,所以选项 A 错误。
  2. 方法重写影响:在 A 的构造方法中调用了 setI(20) 方法,由于 B 类重写了 setI 方法,在创建 B 类对象调用父类 A 构造方法时,此时调用的 setI 方法是 B 类重写后的 setI 方法。
  3. 计算过程B 类的 setI 方法中 this.i = 3 * i ,传入的参数 i 为 20,执行后 this.i 即 A 类中的成员变量 i 的值变为 3 * 20 = 60 ,之后在 A 的构造方法中输出 i from A is 60 ,所以选项 B 和 C 错误,选项 D 正确。

相关文章:

  • Ubuntu学习记录
  • EXIST与JOIN连表比较
  • Flink基本理解
  • 缓存穿透、缓存击穿、缓存雪崩解决方案
  • MySQL 索引详解与原理分析
  • Typescript总结篇——配置TS、基础知识(类型、接口、类型别名、泛型、extendsinfer关键字)
  • 递归+反射+注解(动态拼接建表语句)
  • BitsAndBytesConfig参数描述
  • RESTful风格
  • C++网络编程入门学习(四)-- GDB 调试 学习 笔记
  • 面试题 - 微服务相关的经典问题(33道)
  • 解决echarts图表legend文本太长;echarts图表的图例legend省略号显示
  • 第十节第四部分:常见API:秒杀案例、Calendar
  • SkyWalking 报错:sw_profile_task 索引缺失问题分析与解决
  • Javascript 编程基础(4)函数 | 4.4、bind() 方法
  • 重磅升级!Google Play商店改版上线
  • 13、自动配置【源码分析】-自动包规则原理
  • Postgres数据库配置用户读写权限(read_write)和只读权限(read_only):
  • 第23天-Python Flet 开发指南
  • Quasar 使用 Pinia 进行状态管理
  • 泰安人才网首页/常州seo
  • 校园网站建设情况汇报/培训心得体会总结简短
  • 免费申请网站com域名/多用户建站平台
  • design设计网站/新手如何涨1000粉
  • 湘潭房产网站建设/北京网站建设公司哪家好
  • 北京建设部官方网站证书查询/跨境电商关键词工具