空空叶博客 学习与开发博客

Java学习笔记

2019-03-08
kongkongye

里面放置一些零碎的java知识/注意事项等.

判断JVM运行在Client还是Server模式

使用java -version即可查看

java中有哪些常用的包?

  • java.lang: 提供基础类,是默认导入的包.重要的有Runnable,Object,Math,String,StringBuffer,System,Thread,Throwable
  • java.util: 提供集合框架,事件模型,日期时间,国际化和各种工具类
  • java.io: 通过文件系统,数据流和序列化提供系统输入与输出
  • java.nio: 异步io
  • java.net: 提供网络相关类
  • java.sql
  • java.awt: 提供了创建界面与图像的类
  • javax.swing: 提供一组轻量级组件,以使在不同工作平台上工作方式相同
  • java.text: 提供了与自然语言无关的方式来处理文本,日期,数字和消息的类和接口

java中常用的集合类

  • Collection
    • Set: 不能包含重复元素
      • HashSet
      • TreeSet
    • List: 有序列表
      • ArrayList: 内部使用数组存储,适合查询操作多,增删操作少的情况
      • LinkedList: 内部使用双向链表存储,适合增删操作多,查询操作少的情况
      • Vector: 内部使用数组存储,线程安全
        • Stack
    • Queue
  • Map: 不能包含重复的键,但可以包含重复的值
    • HashMap: 内部使用哈希表实现,线程不安全,允许键或值为null
      • LinkedHashMap: 有序,但遍历比HashMap慢
    • Hashtable: 线程安全,但也因此效率低于HashMap,不允许键或值为null
    • ConcurrentHashMap: 线程安全,并且锁分离.内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的hashtable,它们有自己的锁.只要多个修改操作发生在不同的段上,它们就可以并发进行.
    • TreeMap: 内部使用红黑树实现,不允许键为null

classloader(类加载器)

java默认提供的classloader

  1. Bootstrap ClassLoader(启动类加载器): 加载核心类库,如rt.jar,resources.jar,charsets.jar等

    它不是java类,不继承自ClassLoader,底层由c++编写,嵌入到jvm内核中

  2. Extension ClassLoader(扩展类加载器): 加载扩展类库,默认加载$JAVA_HOME/jre/lib/ext目录下所有jar
  3. App ClassLoader(系统类加载器): 加载应用classpath目录下所有class和jar文件
  4. 自定义类加载器: 必须继承自ClassLoader

加载原理

ClassLoader采用双亲委托模型,使用自上而下的顺序来加载,这样方式的好处有:

  1. 避免重复加载,即父加载器已经加载了,子加载器就不需要重新加载一次.
  2. 安全考虑,比如你没法实现个自定义的String类代替默认的

如何判断两个类是否相同

  1. 由同一类加载器加载
  2. 类名相同

创建对象方式

  1. new
  2. 反射: Constructor的newInstance()方法
  3. clone(): 类必须实现Cloneable接口,否则会抛CloneNotSupportedException异常.

    clone方法会直接复制字段内容,进行浅拷贝. 并且构造函数(及其它的实例语句)不会被调用.

    Object的clone()方法默认是protected的,约定为子类覆盖此接口,并将方法修饰符改为public

  4. 序列化: 实现Serializable接口,调用ObjectInputStream的readObject()方法

其中第3,4条是克隆对象的方式

创建线程方式

  1. 继承Thread: 使用this即可获得当前线程
  2. 实现Runnable: 优点是线程类只是实现了Runnable接口,还能继承其它的类,更加灵活.访问当前线程使用Thread.currentThread()方法

序列化

如果想把对象的属性(不包括方法)保存到文件或数据库,或者通过网络/RMI进行传输,那么就需要序列化.

要序列化的类必须实现Serializable接口,并且所有属性必须是可序列化, 或者给属性加transient关键字表示是短暂的,这个属性就不会被序列化,如敏感的密码字段.

父类实现序列化后,子类也会自动实现自动化.

可以通过ObjectOutputStream进行序列化,通过ObjectInputStream进行反序列化.

是否所有对象都能序列化?

并非所有的对象都可以序列化,原因比如:

  1. 安全方面原因,比如一个对象有private的属性,但序列化后,这些属性值也会暴露
  2. 资源分配方面原因,如socker,thread类,如果可以序列化传输,但资源也无法重新分配

ThreadLocal(线程局部变量)

本质上就是每个线程都维护了一个map,map的key就是ThreadLocal对象,值就是我们set的那个值

java里线程为什么很’贵’?

  1. 线程的创建与销毁成本很高
  2. 线程本身占用较大内存,在java里一个线程至少会分配512k~1M的空间
  3. 线程的切换成本高,切换时需要保存线程上下文,然后执行系统调用.如果线程过多,甚至可能导致切换时间大于线程执行时间.

io流

  1. 字符流: 类名一般以readerwriter结尾
  2. 字节流: 类名一般以stream结尾
  3. 转换流: 将字节流转换为字符流
    • InputStreamReader
    • OutputStreamWriter

finally执行顺序问题

如果try块里有return语句,则finally会在return执行完后,方法返回前执行,如:

//以下代码会先调用a(),再调用b(),然后返回
try {
    return a();
}finally {
    b();
}

error与exception

error与exception都继承自throwable,但error不需要catch

内部类

内部类(inner class)就是定义在一个类中的类

内部类的分类

  • 静态内部类
  • 非静态内部类
    • 成员内部类
    • 方法内部类
    • 匿名内部类

内部类的作用?

  • 内部类可以访问外部类的成员,包括private
  • 内部类可以对同一包中的其他类隐藏
  • 内部类可以实现java’多继承’
  • 回调函数可以使用匿名内部类实现以避免大量代码

内部类与外部类的关系

对于非静态内部类,如果没有外部类的实例是无法创建内部类的

从实现上来说,内部类会被编译为外部类$内部类.class,对于虚拟机来说,并没有内部类的概念,实际就是一个单独的类

非静态内部类的创建方式

  1. 在外部类中new InnerClass()
  2. new OuterClass().new InnerClass()

内部类为什么能访问外部类成员?

当外部类对象创建了内部类对象,内部类对象就获得了外部类对象的引用

注意事项

  1. 非静态内部类不能包含静态成员
  2. 创建外部类的时候不一定要创建内部类
  3. 匿名内部类没有构造方法,因为它没有类名

java注意事项

  • 静态方法无法被覆盖
  • char类型可以储存一个中文汉字,因为java中使用的编码是Unicode
  • 方法可以重载(Overload)和重写(Override),他们都是实现多态的方式
  • 里氏代换原则: 基类可以出现的地方,之类一定可以出现
  • 逻辑比较中,&是逻辑与,&&是短路与(在&&左边为false时,右边不会执行)
  • 逻辑比较中,|是逻辑或,||是短路或(在   左边为true时,右边不会执行)
  • java中有8个基础类型: byte,short,int,long,float,double,char,boolean,其他像String,枚举等都是引用类型

assert断言

断言一般用在开发与测试环境中,主要用来调试. 为了保证效率,生产环境一般不开启.

开启关闭方法

  • 开启断言添加启动参数: -ea
  • 关闭断言添加启动参数: -da(默认无效,因此这个启动参数可以忽略)

使用方法

  1. assert condition;
  2. assert condition:expr;,expr用于断言失败后的提示

stream parallel

什么时候用?

parallel更耗资源,协调线程需要花很多时间,因此不是什么情况都适合的. 适合的情况有:

  • 大量任务要处理,这些任务可并行,并且都很耗时间
  • 不用并行时有性能问题

parallelStream是什么?

parallelStream其实就是一个并行执行的流.它通过默认的ForkJoinPool,可能提高你的多线程任务的速度.


相似文章

上一篇 mysql分库分表

下一篇 Linux学习笔记

目录