Java的一些细节语法(不定时更新。。。)

可信考试Java相关题目

  1. ConcurrentHashMap不允许key为null,但是HashMap是可以的。TreeMap key不支持null。

  2. 以下代码里面,请注意:

    Integer a = 150;
    Integer b = 150;
    Integer c = 100;
    Integer d = 100;
    Integer e = new Integer(100);
    System.out.println(a == b); //false
    System.out.println(a == 150); //true  这种是真正的在对比值的大小
    System.out.println(c == d); //true
    System.out.println(c == e); //false
    
  3. Process类有输出流,输入流,错误流。

  4. 关于nio里面Bufferduplicate方法:

    ByteBuffer buf = ByteBuffer.allocate(100);
    /**
             * duplicate函数的官方注释,并不是真正的复制。
             * Creates a new byte buffer that shares this buffer's content.
             *
             * <p> The content of the new buffer will be that of this buffer.  Changes
             * to this buffer's content will be visible in the new buffer, and vice
             * versa; the two buffers' position, limit, and mark values will be
             * independent.
             * */
    ByteBuffer buf2 = buf.duplicate();
    
  5. Java Stream的数据源有容器,数组和I/O,Stream的中间操作(intermediate function)并不会直接执行,只有遇到终端操作(terminal function)才会开始执行。

  6. 在Java里面, count = count++,会导致count++没有效果,这个从字节码层面是可以解释的。

    	     0: iconst_0
             1: istore_1    // 将0存入到参数1的位置
             2: iload_1     //将参数1的位置,也就是0,读取到操作数栈
             3: iinc          1, 1   //给参数1的位置的参数直接+1
             6: istore_1            //将操作数栈顶,也就是0,存储在参数1的位置
             7: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
            10: iload_1  //将参数1的位置,也就是0,读取到操作数栈
            11: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
            14: return
    

    相对的,count = ++count的字节码如下:

             0: iconst_0
             1: istore_1    // 将0存入到参数1的位置
             2: iinc          1, 1   // 将参数1的位置,也就是0,直接+1,
             5: iload_1     // 读取参数1的位置,也就是1,放在操作数栈
             6: istore_1    // 将操作数栈顶的值,也就是1,存储在参数1的位置
             7: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
            10: iload_1     // 将参数1的位置,也就是1,读取到操作数1栈
            11: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
            14: return
    
    

    注意观察两段代码iinc前后的区别。

  7. Java的栈帧包括:局部变量表,操作数,动态链接,方法返回地址(注意,不包含本地方法栈)

  8. 通过DataSource对象访问的驱动程序本身不会向DriverManager注册,且其对象属性是可以进行更改的,如果服务器配置发生了变化,可以通过更新DataSource来进行对应的适配。

  9. 关于Java里面的<? extends Obj> 协变和<? super Obj>逆变的详细解释:

        static class Parent{
        }
    
        static class FirstChild extends Parent{
        }
    
        static class SecondChild extends Parent{
    
        }
    
        static class FirstGrandChild extends FirstChild{
    
        }
    
        static class FirstGrand2Child extends FirstChild{
        }
    
        static class SecondGrandChild extends SecondChild{
    
        }
    
        static class SecondGrand2Child extends SecondChild{
    
        }
    
    
        public static void main(String[] args) {
            //指定了上界
            List<? extends FirstChild> parentList = new ArrayList<>();
            List<FirstChild> firstChildList = new ArrayList<>();
            firstChildList.add(new FirstGrandChild());
            firstChildList.add(new FirstGrandChild());
            //Parent没有继承FirstChild
    //        parentList = new ArrayList<Parent>();
            //这个是可以的,因为parentList表示该list存储了Parent或者其子类
            parentList = firstChildList;
            //下面这个是不可以的,因为该list存储了Parent或者其子类,那么尝试添加FirstChild就会出错,因为继承了Parent的不仅有FirstChild还有SecondChild。
            // 上面把List<FirstChild>赋值给List<? extends Parent>后,如果添加可以成功的话,那么根据Java泛型实现的方式,就可以添加SecondChild及其子类,
            // 这明显是违背Java的语法规则的,所以这种情况下只能添加null。这称之为协变
    //        parentList.add(new FirstChild());
    
            //但是get是可以的,因为指定了上界,所以可以确定成员一定可以转换为FirstChild
            FirstChild c = parentList.get(0);
    
    
    
            //指定了下界
            List<? super SecondChild> secondList = new ArrayList<>();
            List<Parent> pList = new ArrayList<>();
            secondList = pList;
    
            //不是SecondChild的父类
    //        secondGrandList = new ArrayList<SecondGrand2Child>();
    
            //但是不同于协变,add是可以的,因为可以确定的是,secondList里面成员,一定可以转换成SecondChild或者其父类,
            // 所以这里的add操作是可以的,这叫做逆变。比如说下面的SecondGrandChild和SecondGrand2Child都是可以转换成SecondChild或者其父类的
            secondList.add(new SecondGrandChild());
            secondList.add(new SecondGrand2Child());
    
            //相反的,get操作只能返回Object,因为SecondChild的父类不确定,因此无法确定一个具体的类型,但是Object又是所有类的父类,
            //因此,get返回的只能是Object对象
            Object o = secondList.get(0);
            //这个操作是不可以的
    //        SecondChild child = secondList.get(0);
    
        }
    
posted @ 2020-08-03 17:29  不晓得叫什么  阅读(113)  评论(0编辑  收藏  举报