倚楼听风雨
淡看江湖路

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

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

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

每篇文章更新到100条之后会开新的文章继续随手分享和总结,未完成200条之前会持续更新。喜欢可以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

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通信流程示意图

服务端(必须满足: 绑定一个固定的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: 最终修饰符,指定此变量的值不能变。
  • 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接口重要知识点图示

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

36.待续。

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

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

开始你的表演 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

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

支付宝扫一扫打赏

微信扫一扫打赏