倚楼听风雨
淡看江湖路

[笔记]琐碎的Java基础知识不整理版随手记 持续更新

本文持续更新老四平时敲代码遇到的一些基本知识,一些容易混淆的Java基础知识点,随手记录并分享出来,做一个备忘和时常复习使用,您也可以将这些知识点记录在便笺上随手贴在自己的工作环境,亦可深度解析一下其中的每一条,然后牢牢掌握,以后无论是工作还是笔试面试都可能会助你一臂之力,伟大的coder们加油,Debug yourself!!!!这句话会以后会成为高老四博客的slogan~~

Debug Youself-高老四博客 Java基础知识随手笔记分享 第1张

每篇文章更新到50条之后会开新的文章继续随手分享和总结,持续更新琐碎的Java知识笔记。喜欢的可以Ctrd+d收藏本页面。

1.javac将源程序编译成.class文件,字节码;java将字节码转为机器码,常见的exe程序或者web程序

2.原生类是指Java中,数据类型分为基本数据类型(或叫做原生类、内置类型)和引用数据类型。数组是一种对象

3.运算符优先级顺序口诀: 单运移比按逻三赋 单目(+,-,++,–) > 算数运算符(+,-,*,/,%) > 移位(<<,>>) > 比较(>,<,>=,<=,==,!=) > 按位(&,|,~,^) > 逻辑(&&,||,!) > 三目(表达式1?表达式2:表达式3) > 赋值(=)

4.default和protected的区别:

  • default只要是外部包,就不允许访问。
  • protected只要是子类就允许访问,即使子类位于外部包。

总结: default拒绝一切包外访问;protected接受包外的子类访问。

5.JSP四大作用域:

  • page(作用范围最小)
  • request
  • session
  • application(作用范围最大)

存储在application对象中的属性可以被同一个WEB应用程序中的所有Servlet和JSP页面访问。

存储在session对象中的属性可以被属于同一个会话(浏览器打开直到关闭称为一次会话,且在此期间会话不失效)的所有Servlet和JSP页面访问。

存储在request对象中的属性可以被属于同一个请求的所有Servlet和JSP页面访问(在有转发的情况下可以跨页面获取属性值),例如使用PageContext.forward和PageContext.include方法连接起来的多个Servlet和JSP页面。

存储在pageContext对象中的属性仅可以被当前JSP页面的当前响应过程中调用的各个组件访问,例如: 正在响应当前请求的JSP页面和它调用的各个自定义标签类。

6.标准ASCII只使用7个bit,扩展的ASCII使用8个bit。ASCII码包含一些特殊空字符不能用于打印,而是控制打印机的命令。

7.在创造派生类(子类)的过程中首先创建基类(父类)对象,然后才能创建派生类。创建基类(父类)即默认调用基类的构造方法,在构造方法中可以调用其余普通方法。如果派生类(子类)中存在父类构造器中调用的普通方法,则被调用的普通方法是派生类中的方法。

8.父子类执行顺序: 父类静态域(static声明,JVM加载类的时候执行且执行一次)->子类静态域->父类成员初始化->父类构造块(直接使用{}定义,创建对象是执行)->父类构造方法->子类成员初始化->子类构造块->子类构造方法,所以在创建派生类对象,构造函数的执行顺序为: 基类(父类)构造函数->派生类对象成员构造函数->派生类本身的构造函数。

9.重载必须方法名相同,参数不同,跟返回值没有任何关系

10.Hashtable不允许null键或值,HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。

11.字符流可以理解为字节流+编码集,所以和字符流有关的类都拥有操作编码集(unicode)的能力。

字节流:

  • InputStream
    — FileInputStream(基本文件流)
    — BufferedInputStream
    — DataInputStream
    — ObjectInputStream

字符流:

  • Reader
    — InputStreamReader
    — BufferedReader(常用)
  • Writer
    — OutputStreamWriter
    — BufferedWriter
    — PrintWriter

Java中的I/O留脑图总结 第2张

12.抽象类中可以包含具体的方法,当然也可以不包含抽象方法。

13.Java编程思想: 当编写一个java源代码文件时,此文件通常被称为编译单元(有时也被称为转译单元)。每个编译单元都必须有一个后缀名.java,而在编译单元内则可以有一个public类,该类的名称必须与文件的名称相同(包括大小写,但不包括文件的后缀名.java)。每个编译单元只能有一个public类,否则编译器就不会接受。如果在该编译单元之中还有额外的类的话,那么在包之外的世界是无法看见这些类的,这是因为它们不是public类,而且它们主要用来为主public类提供支持。

上面的话通俗一点来讲就是: 一个Java类文件中public类不是必须的,但是如果源文件中有一个(如果有就只能有一个)public类的话,文件名必须与这个public类同名,原因是为了方便虚拟机在相应的路径中找到相应的类所对应的字节码文件。所以在没有public类的Java文件中,文件名和类名都没什么联系。

14.在异常处理中,try中的代码可能产生多种异常,当然可以对应多个catch语句,如果catch中的参数类型有父类子类关系,此时应该将父类放在后面,子类放在前面。

15.在接口里面的变量默认都是public static final 的,它们是公共的,静态的,最终的常量.相当于全局常量,可以直接省略修符。实现类可以直接访问接口中的变量。

  • 为什么要public修饰? 因为接口必然是要被实现的,用别的修饰就没有意义了
  • 为什么还要static修饰? 因为如果不是static,那么由于每个类可以继承多个接口,你不知道谁就给他修改了或者出现重名了,与设计不符,接口的变量用于全局共享
  • 为什么还要final修饰呢? 接口的设计提现的是设计模式中的开放-封闭原则,接口是一种模板对修改关闭,对扩展开放。关于开放-封闭原则的浅析及相关介绍可以参考一下老四的《浅析设计模式第四章之开放-封闭原则》这篇文章。

16.IoC(Inversion of Control,控制反转)的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。

举例来说比如我们Spring项目中配置的数据库或者数据库连接池,不需要我们操心数据库的连接,如果不看源码你都不知道你的Connection是怎么构造的,何时构造。如果我们自己编写JDBC代码,我们需要通过编码获得Connection对象,但是同Spring等带有依赖注入特性的框架,我们只需要告诉Spring我要使用数据库,我要连接数据库,Spring就会在需要连接数据库的时候动态注入一个Connection对象,想打针似的给你扎进来,通过Sprig来完成各种各样的对象管理和控制。至于如何注入?一般都是同过Java的反射机制来注入,Java反射允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性。

17.基于TCP协议的socket通信流程示意图:

.基于TCP协议的socket通信流程示意图 第3张

服务端(必须满足: 绑定一个固定的IP和端口号、稳定运行并支持开发):

  • 创建套接字描述符(socket)
  • 设置服务器的IP地址和端口号
  • 将套接字描述符绑定到服务器地址(bind)
  • 将套接字描述符设置为监听套接字描述符(listen),等待来自客户端的连接请求,监听套接字维护未完成连接队列和已完成连接队列
  • 从已完成连接队列中取得队首项,返回新的已连接套接字描述符(accept),如果已完成连接队列为空,会阻塞。
  • 从已连接套接字描述符读取来自客户端的请求(read/recv)
  • 向已连接套接字描述符写入应答(write/send)
  • 关闭已连接套接字描述符(close),等待下一个客户端的连接请求

客户端:

  • 创建套接字描述符(socket)
  • 设置服务器的IP地址和端口号
  • 请求建立到服务器的TCP连接并阻塞,直到连接成功建立(connect)
  • 向套接字描述符写入请求(write/send)
  • 从套接字描述符读取来自服务器的应答(read/recv)
  • 关闭套接字描述符(close)

18.i++是先取值再加;++i是先加再取值。

19.String类的两个常用api:

  • String (byte[] bytes, String charsetName) 通过使用指定的charset解码指定的byte数组,构造一个新的字符串。
  • String.getBytes(Charset charset) 使用给定的charset将此String字符串编码到byte序列,并将结果存储到新的byte数组。

20.当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,会抛出InterruptedException异常。

抛出InterruptedException异常标志性方法:

  • java.lang.Object类的wait()方法
  • java.lang.Object类的sleep()方法
  • java.lang.Object类的join()方法

除了列表中以外,还有一个不常见的CyclicBarrier类,CyclicBarrier是一个屏障类,它的await()方法可以简单的理解为: 等待多个线程同时到达之后才能继续进行,在此之前它就是这些线程的屏障,线程不能继续进行。而对于失败的同步尝试,CyclicBarrier使用了一种要么全部要么全不(all-or-none)的破坏模式: 如果因为中断、失败或者超时等原因,导致线程过早地离开了屏障点,那么在该屏障点等待的其他所有线程也将通过BrokenBarrierException(如果它们几乎同时被中断,则用 interruptedException)以反常的方式离开。因此它被中断也是可以抛出interruptedException的。

21.Java一律采用Unicode编码方式,每个字符无论中文还是英文字符都占用2个字节。Java虚拟机中通常使用UTF-16的方式保存一个字符(char)。

22.笔试面试中经常考你的String类相关的一些基础知识:

  • String类是final类,即意味着String类不能被继承,并且它的成员方法都默认为final方法。在Java中,被final修饰的类是不允许被继承的,并且该类中的成员方法都默认为final方法。String类底层是char数组来保存字符串的。对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象
  • 字符串常量池: 在class文件中有一部分来存储编译期间生成的字面常量以及符号引用,这部分叫做class文件常量池,在运行期间对应着方法区的运行时常量池。JVM为了减少字符串对象的重复创建,维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池。当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。字符串常量池实现的前提条件就是Java中String对象是不可变的,这样可以安全保证多个变量共享同一个对象。

23.Java中类是单继承,但接口可以多继承。

24.Java中涉及到byte、short和char类型都可以强制转化为int。

25.Math.cos为计算弧度的余弦值,Math.toRadians()函数将角度转换为弧度;toDegrees()是将弧度转换为角度

26.Java一些并发类的基本特征:

  • CopyOnWriteArrayList 适合使用在读操作远远大于写操作的场景里,比如缓存。
  • ReadWriteLock 当进行写操作时其他线程无法读取或写入数据,而当读操作时,其它线程无法写入数据,但却可以读取数据 。适用于读取远远大于写入的操作。
  • ConcurrentHashMap是一个线程安全的HashTable,它的主要功能是提供了一组和HashTable功能相同但是线程安全的方法。ConcurrentHashMap可以做到读取数据不加锁,并且其内部的结构可以让其在进行写操作的时候能够将锁的粒度保持地尽量地小,不用对整个ConcurrentHashMap加锁。

27.构造函数不能被继承,构造方法只能被显式或隐式的调用。

28.整理一下Java中国修饰符相关的知识点:

修饰符的分类:

  • 访问权限修饰符
  • 非访问权限修饰符

访问权限修饰符:

  • public: 公有访问,对所有的类都可见。
  • protected: 保护型访问,对同一个包可见,对不同的包的子类可见。
  • default: 默认访问权限,只对同一个包可见,对不同的包的子类不可见,区别于protected。
  • private: 私有访问,只对同一个类可见,其余都不可见。

非访问权限修饰符:

  • static: 用来创建类方法和类变量。
  • final: 用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。具体也可以参考一下老四的《Java面向对象之final修饰符》文章。
  • abstract: 用来创建抽象类和抽象方法。
  • synchronized: 用于多线程的同步。
  • volatile: 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样两个不同的线程总是看到某个成员变量的同一个值。详情可以参考一下老四写的《Java关键字volatile浅析 线程安全的利器》这篇文章。
  • transient: 序列化的对象包含被transient修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。关于这个关键字的具体使用和介绍可以参考老四的《Java中I/O输入输出流之对象序列化浅析》这篇文章。

外部类修饰符:

  • public: 访问控制符,将一个类声明为公共类,它可以被任何对象访问,一个程序的主类必须是公共类。
  • default: 也是访问控制符,类只对包内可见,包外不可见。protected和private不能修饰外部类,因为外部类放在包中,只能是包可见和包不可见。 
  • abstract: 非访问控制符,将一个类声明为抽象类,抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充,抽象类可以包含抽象方法和非抽象方法。
  • final: 非访问控制符,将一个类声明为最终类,不能被其他类继承。final和abstract不能同时修饰外部类,因为该类要么能被继承要么不能被继承,只能选其一。
  • 不能用static修饰类,类加载后才会加载静态成员变量,所以不能用static修饰类和接口。

内部类修饰符:

内部类与成员变量地位一致,所以public、protected、default和private均可以修饰,并且static也可以修饰内部类,用来表示嵌套内部类,不用实例化外部类,即可调用。

方法修饰符:

  • public: 公共控制符,包外包内都可以调用该方法。
  • protected: 保护访问控制符,指定该方法可以被它的类和子类进行访问。
  • default: 默认权限控制符,指定该方法只对同包可见,对不同包不可见。
  • private: 私有控制符,指定此方法只能有自己类的方法访问,其他的类不能访问。
  • final: 指定方法不能再进行继承扩充。
  • static: 指定不需要实例化就可以激活的一个方法,在内存中只有一份,通过类名即可调用。
  • synchronize: 同步修饰符,在多个线程中,该修饰符用于在运行前,对它所属的方法加锁,以防止其他线程的访问,运行结束后解锁。
  • native: 本地修饰符,指定此方法的方法体是用其他语言在程序外部编写的。
  • abstract: 抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。抽象方法不能被声明成final和static。任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。 抽象方法的声明以分号结尾。

成员变量修饰符:

  • public: 公共访问控制符,指定该变量为公共的,可以被任何对象的方法访问。
  • protected: 保护访问控制符,指定该变量可以别被自己的类和子类访问。在子类中可以覆盖此变量。
  • default: 默认权限,指定该变量只对同包可见,对不同包不可见。
  • private: 私有访问控制符,指定该变量只允许自己的类的方法访问,其他任何类中的方法均不能访问。
  • final: 最终修饰符,指定此变量的值不能变。注意: final型的成员变量不必一开始就赋值,也可以在构造方法中赋值,但一定要赋值,且不能被修改。
  • static: 静态修饰符,指定变量被所有对象共享,即所有实例都可以使用该变量,变量属于这个类。final和static经常一起使用来创建常量。
  • transient: 过度修饰符,指定该变量是系统保留,暂无特别作用的临时性变量,不持久化。
  • volatile: 易失修饰符,指定该变量可以同时被几个线程控制和修改,保证两个不同的线程总是看到某个成员变量的同一个值。

局部变量修饰符:

只有final修饰符可以修饰局部变量。局部变量的生命周期为一个方法的调用期间,所以没必要为其设置权限访问字段,变量在方法调用期间已经被加载进了虚拟机栈。换句话说就是肯定能被当前线程访问到,所以设置没意义。 那为什么不能用static修饰局部变量呢?静态变量在方法之前先加载的,方法后加载,方法中使用static与设计规则就冲突了,这个应该很好理解。

接口修饰符:

  • 接口修饰符只能用public、default和abstract。 不能用final、static修饰。默认修饰为abstract。
  • 接口中方法中修饰符只能是public和abstract修饰,不写默认也是public abstract。 在Java1.8之后,接口允许定义static静态方法,所以也可以用static来修饰!

形参修饰符:

对于形式参数只能用final修饰符,其它任何修饰符都会引起编译器错误。但是用这个修饰符也有一定的限制,就是在方法中不能对参数做任何修改。一般情况下,一个方法的形参不用final修饰。只有在特殊情况下,那就是方法内部类。一个方法内的内部类如果使用了这个方法的参数或者局部变量的话,这个参数或局部变量应该是final。

29.子类将继承父类所有的数据域和方法。有些是不能调用,比如父类的静态方法不能直接调用,但不能说没继承。

30.java的基本编程单元是类,基本存储单元是变量。

31.HashMap的底层是由数组加链表实现的,对于每一个key值,都需要计算哈希值,然后通过哈希值来确定顺序,并不是按照加入顺序来存放的,因此可以认为是无序的,但不管是有序还是无序,它都一个自己的顺序。HashMap允许将null用作值,HashMap允许将null用作键,但是Hashtable是不允许key和value的值为空的。

32.接口中只有常量定义,没有变量声明。

33.在根类Object中包含以下方这些方法:

  • clone()
  • equals()
  • finalize()
  • getClass()
  • notify(),notifyAll()
  • hashCode()
  • toString()
  • wait()

34.Java集合相关的重要知识点图示:

Java中Collection和Map接口重要知识点图示 第4张

35.声明的二维数组中第一个中括号中必须要有值,它代表的是在该二维数组中有多少个一维数组。

36.char < short < int < float < doublejuhao5不同类型运算结果类型向右边靠齐。

37.类的编写需要遵守先继承再实现: public class A extends B implements C {}

38.泛型仅仅是java的语法糖,它不会影响java虚拟机生成的汇编代码,在编译阶段,虚拟机就会把泛型的类型擦除,还原成没有泛型的代码,顶多编译速度稍微慢一些,执行速度是完全没有什么区别的。关于泛型详细一点的介绍可以参考一下老四的这篇《浅析Java中的泛型以及泛型中的PECS(Producer Extends,Consumer Super)原则》文章。

39.方法重写应遵循「三同一小一大」原则:

  • 「三同」方法名相同,形参列表相同,返回值类型相同
  • 「一小」子类方法声明抛出的异常比父类方法声明抛出的异常更小或者相等
  • 「一大」子类方法的访问修饰符应比父类方法更大或相等

40.简单说一下Java中的前台线程与后台线程的之间的联系与区别。

我们常用的main()函数就是一个前台线程,前台线程指的是程序中必须执行完成的。而后台线程主要负责内存分配方面的事情,后台线程是在Java中所有前台线程结束之后才结束。

  • 后台线程不会阻止进程的终止。属于某个进程的所有前台线程都终止后,该进程就会被终止。所有剩余的后台线程都会停止且不会完成。
  • 可以在任何时候将前台线程修改为后台线程,方式是设置 Thread.IsBackground 属性。
  • 不管是前台线程还是后台线程,如果线程内出现了异常,都会导致进程的终止。
  • 托管线程池中的线程都是后台线,使用new Thread方式创建的线程默认都是前台线程。

关于上面最后一条: 应用程序的主线程以及使用Thread构造的线程都默认为前台线程 。使用Thread建立的线程默认情况下是前台线程,在进程中,只要有一个前台线程未退出,进程就不会终止。主线程就是一个前台线程。而后台线程不管线程是否结束,只要所有的前台线程都退出(包括正常退出和异常退出)后,进程就会自动终止。一般后台线程用于处理时间较短的任务,如在一个Web服务器中可以利用后台线程来处理客户端发过来的请求信息。而前台线程一般用于处理需要长时间等待的任务,如在Web服务器中的监听客户端请求的程序,或是定时对某些系统资源进行扫描的程序。

41.wait()、notify()和notifyAll()都是 Object 类中的方法:

  • wait()、notify()和notifyAll()方法是本地方法,并且为final方法,无法被重写。
  • 调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor(锁)
  • 调用某个对象的notify()方法能够唤醒一个正在等待这个对象的 monitor 的线程,如果有多个线程都在等待这个对象的 monitor ,则只能唤醒其中一个线程;
  • 调用notifyAll()方法能够唤醒所有正在等待这个对象的 monitor 的线程;

除此之外,在jdk1.5中还有一个Condition接口,Condition接口声明了await()和signal()方法,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition1的await()、signal()这种方式实现线程间协作更加安全和高效。Condition依赖于Lock接口,生成一个Condition的基本代码是 lock.newCondition() 调用Condition的await()和signal()方法,都必须在 lock 保护之内,就是说必须在lock.lock()和lock.unlock之间才可以使用 Conditon 中的await()对应Object的wait();Condition中的signal()对应Object的notify();Condition中的signalAll()对应Object的notifyAll()方法。

42.full GC触发的条件:
除直接调用System.gc会触发 full GC ,触发 Full GC 执行的情况有如下四种:

  • 旧生代空间不足: 旧生代空间只有在新生代对象转入及创建大对象、大数组时才会出现不足的现象,当执行 Full GC 后空间仍然不足,则抛出如下错误: java.lang.OutOfMemoryError: Java heap space 为避免以上两种状况引起的FullGC,调优时应尽量做到让对象在Minor GC阶段被回收、让对象在新生代多存活一段时间及不要创建过大的对象及数组。
  • Permanet Generation空间满: Permanet Generation(持久代) 中存放的为一些 class 的信息等,当系统中要加载的类、反射的类和调用的方法较多时,Permanet Generation 可能会被占满,在未配置为采用 CMS GC (Concurrent Low Pause Collector)的情况下会执行 Full GC。如果经过 Full GC 仍然回收不了,那么JVM会抛出如下错误信息: java.lang.OutOfMemoryError: PermGen space ,为避免 Permanet Generation 占满造成 Full GC 现象,可采用的方法为增大 Permanet Generation 空间或转为使用 CMS GC。
  • CMS GC 时出现 promotion failed 和 concurrent mode failure : 对于采用 CMS 进行旧生代 GC 的程序而言,尤其要注意 GC 日志中是否有 promotion failed 和 concurrent mode failure 两种状况,当这两种状况出现时可能会触发 Full GC 。promotion failed 是在进行 Minor GC 时,survivor space 放不下、对象只能放入旧生代,而此时旧生代也放不下造成的; concurrent mode failure 是在执行 CMS GC 的过程中同时有对象要放入旧生代,而此时旧生代空间不足造成的。
    应对措施为: 增大 survivor space、旧生代空间或调低触发并发GC的比率,但在 JDK1.6 的版本中有可能会由于 JDK 的bug导致 CMS 在 remark 完毕后很久才触发 sweeping 动作。对于这种状况,可通过设置 -XX:CMSMaxAbortablePrecleanTime=5 (ms)来避免。
  • 统计得到的 Minor GC 晋升到旧生代的平均大小大于旧生代的剩余空间: 这是一个较为复杂的触发情况, Hotspot 为了避免由于新生代对象晋升到旧生代导致旧生代空间不足的现象,在进行 Minor GC 时,做了一个判断,如果之前统计所得到的 Minor GC 晋升到旧生代的平均大小大于旧生代的剩余空间,那么就直接触发Full GC。
    例如程序第一次触发 MinorGC 后,有6MB的对象晋升到旧生代,那么当下一次 Minor GC 发生时,首先检查旧生代的剩余空间是否大于6MB,如果小于6MB,则执行 Full GC。
    当新生代采用 PSGC 时,方式稍有不同, PS GC 是在 Minor GC 后也会检查,例如上面的例子中第一次 Minor GC 后,PS GC 会检查此时旧生代的剩余空间是否大于6MB,如小于,则触发对旧生代的回收。

除了以上4种状况外,对于使用 RMI(Remote Method Invocation,远程方法调用) 来进行 RPC 或管理的 Sun JDK 应用而言,默认情况下会一小时执行一次 Full GC。可通过在启动时通过 -java-Dsun.rmi.dgc.client.gcInterval=3600000 来设置 Full GC 执行的间隔时间或通过 -XX:+DisableExplicitGC 来禁止 RMI 调用 System.gc。

43.数组定义后,默认元素为0

44.抽象类和接口不能实例化

45.InputStream字节流输入流;InputStreamReader是对字符流的处理,inputStreamReader将字符流处理成字节流,stream是代表字节流的处理。stream 结尾基本都是字节流,reader 和 writer 结尾基本都是字符流;两者的区别就是读写的时候一个是按字节读写,一个是按字符。PushbackInputStream 属于回退流。

46.Java表达式转型规则由低到高转换:

  • 所有的byte,short,char型的值将被提升为int型;
  • 如果有一个操作数是long型,计算结果是long型;
  • 如果有一个操作数是float型,计算结果是float型;
  • 如果有一个操作数是double型,计算结果是double型;
  • 被fianl修饰的变量不会自动改变类型,当2个final修饰相操作时,结果会根据左边变量的类型而转化。

47.方法可以和类同名,区别在于构造器没有返回类型。

48.无符号右移,高位用0填充

49.重点:简单说一下Java中for循环的的执行顺序:

参考上述伪代码,for循环的执行顺序如下:

  • 第一次循环,即初始化循环。首先执行表达式 expression1(一般为初始化语句);再执行 expression2(一般为条件判断语句),判断 expression1 是否符合 expression2 的条件;如果符合,则执行 expression4,否则,停止执行;最后执行 expression3。
  • 第 N(N≥2)次循环。首先执行 expression2,判断在 expression3 是否符合在 expression2 要求;如果符合,则继续执行在 expression4,否则,停止执行。最后执行在expression3。如此往复,直至 expression3 不满足在 expression2 条件是为止。

50.经常鄙视面试中出现的关于 String 的知识点可以参考一下下面的代码,自己好好研究一下:

更博不易,如果觉得文章对你有帮助并且有能力的老铁烦请捐赠盒烟钱,点我去赞助。或者扫描文章下面的微信/支付宝二维码打赏任意金额(点击「给你买杜蕾斯」),也可扫描小站放的支付宝领红包二维码,线下支付享受优惠的同时老四也可以获得对应赏金,老四这里抱拳谢谢诸位了。捐赠时请备注姓名或者昵称,因为您的署名会出现在赞赏列表页面,您的捐赠钱财也会被用于小站的服务器运维上面,再次抱拳感谢。

赞(29) 给你买杜蕾斯
本站原创文章受自媒体平台原创保护,未经允许不得转载高老四博客 » [笔记]琐碎的Java基础知识不整理版随手记

开始你的表演 抢沙发

觉得文章有用就打赏一下老四,鼓励我更好的创作

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册