1

叨叨两句

  1. 果然靠谱,哈哈

  2. 不去见做的好的怎么做,你就永远不知道自己还有哪些地方可以提高

牛客网——java专项练习030

1

关于抽象类和接口叙述正确的是? ( )

正确答案: D

  1. 抽象类和接口都能实例化的

  2. 抽象类不能实现接口

  3. 抽象类方法的访问权限默认都是public

  4. 接口方法的访问权限默认都是public

抽象类
特点: 
1.抽象类中可以构造方法 
2.抽象类中可以存在普通属性,方法,静态属性和方法。 
3.抽象类中可以存在抽象方法。 
4.如果一个类中有一个抽象方法,那么当前类一定是抽象类;抽象类中不一定有抽象方法。 
5.抽象类中的抽象方法,需要有子类实现,如果子类不实现,则子类也需要定义为抽象的。 
6,抽象类不能被实例化,抽象类和抽象方法必须被abstract修饰
关键字使用注意: 
抽象类中的抽象方法(其前有abstract修饰)不能用private、static、synchronized、native访问修饰符修饰。
接口
1.在接口中只有方法的声明,没有方法体。 
2.在接口中只有常量,因为定义的变量,在编译的时候都会默认加上public static final 
3.在接口中的方法,永远都被public来修饰。 
4.接口中没有构造方法,也不能实例化接口的对象。(所以接口不能继承类) 
5.接口可以实现多继承 
6.接口中定义的方法都需要有实现类来实现,如果实现类不能实现接口中的所有方法则实现类定义为抽象类。 
7,接口可以继承接口,用extends

2

Math.round(11.5) 等于:()
正确答案: C

  1. 11

  2. 11.5

  3. 12

  4. 12.5

首先要注意的是它的返回值类型是long,如果 Math.round(11.5f),那它的返回值类型就是int,这一点可以参考API
其次  Returns the closest long to the argument, with ties rounding to positive infinity
它返回的是一个最接近参数的long 值(例如: Math.round(11.6) = 12; Math.round(-11.6) = -12; Math.round(-0.1) = 0; Math.round(0.1) = 0 ),那如果出现向上向下距离一样的数值, 比如题目中的11.5,该如何处理呢 ,别着急,看它的后半句话, with ties rounding to positive infinity( 同时向正无穷方向取舍或者翻译成取较大的值,英语水平较差,只能翻译成这样了;
例子:    Math.round(11.5)  ,首先与 11.5最接近的有两个整数 11 和 12,取较大的那结果就是12;
           Math.round(-11.5), 首先与 -11.5最接近的有两个整数 -11 和 -12,取较大的那结果就是-11;
           Math.round(0.5), 首先与 0.5最接近的有两个整数 0 和 1,取较大的那结果就是1;
           Math.round(-0.5), 首先与 -0.5最接近的有两个整数 -1 和 0,取较大的那结果就是0; )
然后它有三个特例:
1. 如果参数为 NaN(无穷与非数值) ,那么结果为 0。
2.如果参数为负无穷大或任何小于等于 Long.MIN_VALUE 的值,那么结果等于Long.MIN_VALUE 的值。
3.如果参数为正无穷大或任何大于等于 Long.MAX_VALUE 的值,那么结果等于Long.MAX_VALUE 的值。
最后 最好还是看一下API或者源码,不要信了我的邪
round方法,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11。 ceil是天花板,向上取整。 floor是地板,向下去整。

3

下列哪一种叙述是正确的()
正确答案: D

  1. abstract修饰符可修饰字段、方法和类

  2. 抽象方法的body部分必须用一对大括号{ }包住

  3. 声明抽象方法,大括号可有可无

  4. 声明抽象方法不可写出大括号

abstract修饰符可修饰字段、方法和类. × abstract只能用来修饰类、方法,不修饰字段(属性)。
抽象方法的body部分必须用一对大括号{ }包住. × 抽象方法用“;”结束。
声明抽象方法,大括号可有可无. × 抽象方法没有方法体,也不用大括号。

4

What results from the following code fragment?

int i = 5;
int j = 10;
System.out.println(i + ~j);

  1. Compilation error because”~”doesn’t operate on integers

  2. -5

  3. -6

  4. 15

链接:https://www.nowcoder.com/questionTerminal/a568949ffbfc4a20977a2dab786032dd
来源:牛客网

我认为应该是:
计算机本身储存的就是补码:
那么10的补码就是10的原码:0000 0000 0000 1010——这是补码,因为现在是计算机在计算
~10的补码就是:1111 1111 1111 0101
~10的反码就是:1111 1111 1111 0100——补码减1
~10的原码就是:1000 0000 0000 1011——反码取反:这个才是正常二进制数,换算为整数为-11
原码才可以对应为正常的整数,补码只有转换为原码才能被正常人类识别
公式-n=~n+1可推出~n=-n-1,所以~10=-11再加5结果为-6

5

用命令方式运行以下代码的运行结果是()

public class f{

public static void main(String[] args){
    String foo1 = args[1];
    String foo2 = args[2];
    String foo3 = args[3];
}

}
命令: java T11 a b c

  1. 程序编译错误

      1. c

  2. 程序运行错误

  3. t11

运行java命令,没有T11对应的类,会报找不到或者无法加载主类。
 这里java T11 a b c表示 运行java字节码文件 T11  参数为 a b c只输入了三个参数,且args是数组下标从0开始,而程序中使用到agrs[3]显然数组越界
命令:  java T11 a b c,依次是命令 类名  参数。由于没有找到相应的类名所对应的类,所以编译会报错。

6

以下代码将打印出

public static void main (String[] args) {

String classFile = "com.jd.". replaceAll(".", "/") + "MyClass.class";
System.out.println(classFile);

}
正确答案: C 你的答案: B (错误)

  1. com. jd

  2. com/jd/MyClass.class

  3. ///////MyClass.class

  4. com.jd.MyClass

C。由于replaceAll方法的第一个参数是一个正则表达式,而"."在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成"/"。如果想替换的只是".",那么久要写成"\\.".

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

  1. null

  2. sub

  3. base

new Sub();在创造派生类的过程中首先创建基类对象,然后才能创建派生类。
创建基类即默认调用Base()方法,在方法中调用callName()方法,由于派生类中存在此方法,则被调用的callName()方法是派生类中的方法,此时派生类还未构造,所以变量baseName的值为null
1.首先,需要明白类的加载顺序。
(1) 父类静态代码块(包括静态初始化块,静态属性,但不包括静态方法)
(2) 子类静态代码块(包括静态初始化块,静态属性,但不包括静态方法 )
(3) 父类非静态代码块( 包括非静态初始化块,非静态属性 )
(4) 父类构造函数
(5) 子类非静态代码块 ( 包括非静态初始化块,非静态属性 )
(6) 子类构造函数
其中:类中静态块按照声明顺序执行,并且(1)和(2)不需要调用new类实例的时候就执行了(意思就是在类加载到方法区的时候执行的)
2.其次,需要理解子类覆盖父类方法的问题,也就是方法重写实现多态问题。
Base b = new Sub();它为多态的一种表现形式,声明是Base,实现是Sub类, 理解为 b 编译时表现为Base类特性,运行时表现为Sub类特性。
当子类覆盖了父类的方法后,意思是父类的方法已经被重写,题中 父类初始化调用的方法为子类实现的方法,子类实现的方法中调用的baseName为子类中的私有属性。
由1.可知,此时只执行到步骤4.,子类非静态代码块和初始化步骤还没有到,子类中的baseName还没有被初始化。所以此时 baseName为空。 所以为null。
public class Base {
    private String baseName = "base";
    public Base() {
        callName();
    }
    public void callName() {
        System.out.println(baseName);
    }
    public static void main(String[] args) {
        Base b = new Sub();
    }
}
class Sub extends Base {
    private String baseName = "sub";
    public void callName() {
        System.out.println(baseName);
    }
}
本题与内部类无关系,去掉内部类后代码如上,
执行 Base b = new Sub();时由于多态 b编译时表现为Base类特性,运行时表现为Sub类特性,
Base b = new Sub();不管是哪种状态都会调用Base构造器执行 callName()方法;
执行方法时,由于多台表现为子类特性,所以会先在子类是否有 callName();
而此时子类尚未初始化(执行完父类构造器后才会开始执行子类),
如果有就执行,没有再去父类寻找
如果把父类 callName()改为 callName2(),则会输出base

Wall_Breaker
2.1k 声望1.2k 粉丝

生死之间,就是我的跃迁之路,全程记录,欢迎见证