java刷题2020年9月12日

  1. 下列程序执行后结果为( )

     class A {
         public int func1(int a, int b) {
             return a - b;
         }
     }
     class B extends A {
         public int func1(int a, int b) {
             return a + b;
         }
     }
     public class ChildClass {
         public static void main(String[] args) {
         A a = new B();
         B b = new B();
         System.out.println("Result=" + a.func1(100, 50));
         System.out.println("Result=" + b.func1(100, 50));
         }
     }
    

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

    Result=150Result=150
    Result=100Result=100
    Result=100Result=150
    Result=150Result=100
    解释:
    其实很简单,涉及转型的题目,分为向上或者向下转型。
    关键的来了,不论向上或者向下转型,都是一句话,“编译看左边,运行看右边”。也就是编译时候,会看左边引用类型是否能正确编译通过,运行的时候是调用右边的对象的方法。
    就本题来说,编译时候会发现左边满足条件所以编译通过,运行时候又会调用右边也就是 class B 的方法,所以答案都是150。
    此题考查的是多态。
      对于多态,可以总结它为:       
         一、使用父类类型的引用指向子类的对象;
    
        二、该引用只能调用父类中定义的方法和变量;
    
        三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)
    
        四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。
    
    多态的3个必要条件:
    
            1.继承   2.重写   3.父类引用指向子类对象。
    
    向上转型: Person p = new Man() ; //向上转型不需要强制类型转化
    向下转型: Man man = (Man)new Person() ; //必须强制类型转化
    
  2. list和set、map的比较:
      1. List 是一个有序集合,可以存放重复的数据 (有序:存进是什么顺序,取出时还是什么顺序)
                    (1).ArrayList 底层是数组适合查询,不适合增删元素。
                    (2).LiskedList 底层是双向链表适合增删元素,不适合查询操作。
                    (3).Vector 底层和ArrayList相同,但是Vector是线程安全的,效率较低很少使用
       2. Set 是一个无序集合,不允许放重复的数据 (无序可重复,存进和取出的顺序不一样)
                    (1).HashSet 底层是哈希表/散列表
                    (2).TreeSet 继承sartedSet接口(无需不可重复,但存进去的元素可以按照元素的大小自动排序)
       3. Map 是一个无序集合,以键值对的方式存放数据,键对象不允许重复,值对象可以重复。
                    (1).HashMap实现不同步,线程不安全。  HashTable线程安全
                    (2).HashMap中的key-value都是存储在Entry中的。
                    (3).HashMap可以存null键和null值,不保证元素的顺序恒久不变,它的底层使用的是数组和链表,通过hashCode()方法和equals方法保证键的唯一性
    
  3. 以下代码执行后输出结果为( )

    public class ClassTest{
         String str = new String("hello");
         char[] ch = {'a','b','c'};
         public void fun(String str, char ch[]){
         str="world";
         ch[0]='d';
     }
     public static void main(String[] args) {
         ClassTest test1 = new ClassTest();
         test1.fun(test1.str,test1.ch);
         System.out.print(test1.str + " and ");
         System.out.print(test1.ch);
         }
     }
    

    正确答案: A 你的答案: D (错误)

    hello and dbc
    world and abc
    hello and abc
    world and dbc
    解释:
    java中都是按栈中的值传递,基本数据类型栈中的值就是实际存储的值,引用类型栈中的值就是指向堆中的地址
    1)String和char[ ]都是引用类型,所以在方法中传递的都是指向真实数据的地址
    2)假设String str指向的hello的地址为d1,str传递到fun函数中的也是地址d1,成员变量str和fun的形参str不是同一个变量,把fun型中的str赋值为world只是修改了该str指向的地址,该地址由d1更改成了world的地址,并没有改变成员变量str指向的地址及堆中的数据,所以str还是hello。
    3)假设char[ ] ch指向的abc的地址是d2,传递到fun函数中的地址也是d2,同上成员变量ch和fun的形参ch不是同一个变量,(1)如果把fun中的ch[0]='d'更改为ch = new ch[3];ch[0]='d',那么成员变量ch的值是没有变化的,还是abc,原理同上String,只是改变了引用ch指向的堆数据的地址,并没有改变成员变量ch指向的地址以及堆中的数据。(2)改变了堆中的数据,所以最终结果编程dbc,此ch只是形参而不是成成员变量ch,如果对ch变化对成员变量ch没有影响,但是ch[i]指向了堆数据的地址,直接修改堆数据,所以成员变量变了。
    
  4. final、finally和finalize的区别中,下述说法正确的有?

    正确答案: A B 你的答案: A B D (错误)

    A final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
    B finally是异常处理语句结构的一部分,表示总是执行。
    C finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源的回收,例如关闭文件等。
    D 引用变量被final修饰之后,不能再指向其他对象,它指向的对象的内容也是不可变的。
    解释:
    选AB
    A,D考的一个知识点,final修饰变量,变量的引用(也就是指向的地址)不可变,但是引用的内容可以变(地址中的内容可变)。
    B,finally表示总是执行。但是其实finally也有不执行的时候,但是这个题不要扣字眼。
    1. 在try中调用System.exit(0),强制退出了程序,finally块不执行。
    2. 在进入try块前,出现了异常,finally块不执行。
    C,finalize方法,这个选项错就错在,这个方法一个对象只能执行一次,只能在第一次进入被回收的队列,而且对象所属于的类重写了finalize方法才会被执行。第二次进入回收队列的时候,不会再执行其finalize方法,而是直接被二次标记,在下一次GC的时候被GC。
    
 posted on 2020-09-12 09:19  ben跑的换行符  阅读(123)  评论(0编辑  收藏  举报