牛客网专项练习——Java 专项练习(1 ~ 10)

1、下面有关java实例变量,局部变量,类变量和final变量的说法,错误的是?

A. 实例变量指的是类中定义的变量,即成员变量,如果没有初始化,会有默认值。

B. 局部变量指的是在方法中定义的变量,如果没有初始化,会有默认值

C. 类变量指的是用static修饰的属性

D. final变量指的是用final 修饰的变量

答案: B

解析:

  • 定义在类中的变量是类的成员变量,也叫实例变量,可以不进行初始化,Java 会自动进行初始化。如果是基本数据类型,如 int,则会默认初始化为 0;如果是引用数据类型,默认初始化为 null。
  • 局部变量是定义在方法中的变量,Java 虚拟机不会对其进行初始化,所以编程者必须在使用该变量之前给它赋值,否则编译时会报错。
  • 被 static 关键字修饰的变量是静态的,静态变量随着类的加载而加载,所以也被称为类变量
  • 被 final 修饰的变量是常量。
2、关于下面的程序 Test.java 说法正确的是( )。
public class Test {
    static String x = "1";
    static int y = 1;
    public static void main(String args[]) {
        static int z = 2;
        System.out.println(x + y + z);
    }
}

A. 3

B. 112

C. 13

D. 程序有编译错误

答案: D

解析:

static int z = 2; 报错。被 static 修饰的变量称为静态变量,也叫类变量,属于整个类;而局部变量属于方法,只在该方法内有效,所以不能用 static 修饰局部变量。

另外,对比下面的几句代码,

System.out.println(1 + 2 + "3");// 33
System.out.println(1 + (2 + "3"));// 123
System.out.println("1" + 2 + 3);// 123
System.out.println(1 + "2" + 3);// 123

如果没有括号,系统会按照从左到右的顺序依次执行 “+” 运算。因此 1+2+“3” 会先执行1+2,其结果 3 再与 “3” 相加,即为 33。

3、说明程序输出结果。
package algorithms.com.guan.javajicu; 
public class Inc { 
    public static void main(String[] args) { 
       Inc inc = new Inc(); 
       int i = 0; 
       inc.fermin(i); 
       i= i ++; 
       System.out.println(i);
    
    } 
    void fermin(int i){ 
       i++; 
    } 
}

A. 0

B. 1

C. 2

D. 3

答案: A

解析:

首先,i++ 也是一个表达式,是有返回值的,返回值就是 i 自增前的值。因此执行 i = i++ 后,虽然 i 自增为 1,但是 i++ 的返回值(0)又给 i 重新赋值了;

其次,fermin(int i) 方法的形参 i 只在方法内有效,改变的是方法自己的 i,不会影响方法外的 i 。

4、以下代码执行后输出结果为( )
public class Test {
    public static void main(String[] args) {
        System.out.println("return value of getValue(): " +
        getValue());
    }
     public static int getValue() {
         try {
             return 0;
         } finally {
             return 1;
         }
     }
 }

A. return value of getValue(): 1

B. return value of getValue(): 0

C. return value of getValue(): 0return value of getValue(): 1

D. return value of getValue(): 1return value of getValue(): 0

答案: A

解析:

根据官方的JVM规范:

如果 try 语句里有 return,返回的是 try 语句块中的变量值。

详细执行过程如下:

  • 如果有返回值,就把返回值保存到局部变量中;
  • 执行 jsr 指令跳到 finally 语句里执行;
  • 执行完 finally 语句后,返回之前保存在局部变量表里的值。

如果 try,finally 语句里均有 return,忽略 try 的 return,而使用 finally 的 return。

5、非抽象类实现接口后,必须实现接口中的所有抽象方法,除了abstract外,方法头必须完全一致.

正确

错误

答案: 错误

解析:

方法头指:修饰符+返回类型 +方法名(形参列表)

关于接口和其实现类,有两同两小一大原则

  • 方法名相同;
  • 参数类型相同;
  • 子类返回类型小于等于父类方法返回类型;
  • 子类抛出异常小于等于父类方法抛出异常;
  • 子类访问权限大于等于父类方法访问权限。
6、有如下一段代码,请选择其运行结果()
public class StringDemo{
  private static final String MESSAGE="taobao";
  public static void main(String [] args) {
    String a ="tao"+"bao";
    String b="tao";
    String c="bao";
    System.out.println(a==MESSAGE);
    System.out.println((b+c)==MESSAGE);
  }
}

A. true true

B. false false

C. true false

D. false true

答案: C

解析:

这题是在考编译器的优化,hotspot 中编译时 “tao”+“bao” 将直接变成 “taobao”,b+c 则不会优化,因为不知道在之前的步骤中 bc 会不会发生改变,而针对 b+c 则是用语法糖,新建一个 StringBuilder 来处理。

7、下面代码的输出是什么?
public class Base
{
    private String baseName = "base";
    public Base()
    {
        callName();
    }
 
    public void callName()
    {
        System. out. println(baseName);
    }
 
    static class Sub extends Base
    {
        private String baseName = "sub";
        public void callName()
        {
            System. out. println (baseName) ;
        }
    }
    public static void main(String[] args)
    {
        Base b = new Sub();
    }
}

A. null

B. sub

C. base

答案: A

解析:

本题与内部类没有关系。

  • 执行 Base b = new Sub();时,由于多态 b 编译时表现为 Base 类特性,运行时表现为 Sub 类特性,所以 Base b = new Sub();不管是哪种状态都会调用 Base 构造器执行 callName() 方法;
  • 执行方法时,由于多态表现为子类特性,所以会先在子类是否有 callName();
    而此时子类尚未初始化(执行完父类构造器后才会开始执行子类),如果有就执行,没有再去父类寻找。
8、假定Base b = new Derived(); 调用执行b.methodOne()后,输出结果是什么?
public class Base
{
   public void methodOne() // (2)
   {
      System.out.print("A");
      methodTwo(); 
   }
 
   public void methodTwo() // (4)
   {
      System.out.print("B");
   }
}
 
public class Derived extends Base
{
   public void methodOne() // (1)
   {
      super.methodOne();
      System.out.print("C");
   }
 
   public void methodTwo() // (3)
   {
      super.methodTwo();
      System.out.print("D");
   }
}

A. ABDC

B. AB

C. ABCD

D. ABC

答案: A

解析:

用多态创建子类对象(向上转型),则在调用一个父类的被子类重写的方法时,不管是在子类中调用还是在父类中调用,不被 super 调用都是调用子类方法,只有用 super 调用时才是调用父类的方法。上面代码执行的调用顺序如注释所示。

9、在开发中使用泛型取代非泛型的数据类型(比如用ArrayList取代ArrayList),程序的运行时性能会变得更好。()

A. 正确

B. 错误

答案: B

解析:

泛型仅仅是 Java 的语法糖,它不会影响 Java 虚拟机生成的汇编代码,在编译阶段,虚拟机就会把泛型的类型擦除,还原成没有泛型的代码,顶多编译速度稍微慢一些,执行速度是完全没有什么区别的。

10、对文件名为 Test.java 的 java 代码描述正确的是( )
class Person {
    String name = "No name";
    public Person(String nm) {
        name = nm;
    }
}
class Employee extends Person {
    String empID = "0000";
    public Employee(String id) {
        empID = id;
    }
}
public class Test {
    public static void main(String args[]) {
        Employee e = new Employee("123");
        System.out.println(e.empID);
    }
}

A. 输出:0000

B. 输出:123

C. 编译报错

D. 输出:No name

答案: C

解析:

子类的构造方法总是先调用父类的构造方法。如果子类的构造方法没有显式地调用父类的构造方法,那么默认调用父类地无参构造方法。

本题中,父类没有无参构造方法,所以子类需要在自己的构造方法中显式地调用父类的构造方法,不然编译器会报错。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值