Java系统库常用API


java.lang包

Java常用基础包,在开发中会自动导入到代码环境中,不需要import。

基本数据类型/包装类

  • 基本数据类型:byte、short、int、long、float、double、char、boolean
  • 包装类:
    • Byte:提供了将字节数据转换为其他类型的方法,从Number抽象类继承过来.decode:将各种进制的数据内容的字符串,转换为十进制标识的字节类型,数字进制的标识符:无标识符:按十进制转换;ox、OX、#:按十六进制转换;o:按八进制转换.
    • Short、Integer:将short、Integer装换为其数据类型的方法,从Number抽象类继承过来。decode与Byte类中的decode方法一样可进行不同进制的装换。parseShort、parseInt、parseByte一样,可以进行不同的进制装换值。(针对值在-128~127之间的数据,无需开辟新空间,存在数据缓冲池中)
      注意:Integer十进制转其他进制的方法:toBinaryString()、toHexString()、toOctalString()。
    • Float、Double:isInfinite():用于判断数字是否有趋近无穷大,无法完整描述的情况。isNaN():判断浮点数据是否为有效数据(浮点类型参与运算后用于判断是否有效)
      容易丢失精度,数据严谨时采用BigDecimal类计算
      注:valueOf、parseXXX方法可以将字符串形式的值装换为数字。
  • 包装类与基本数据类型之间可以实现数据类型的自动转换,即装箱和拆箱。(JDK5新特性)初始化不可以赋空值,如Integer x=null,会报空指针异常
    • 装箱:自动将基本数据类型转换为其对应的包装类.
    • 拆箱:自动将包装类型转换为基本数据类型.

数学运算类

Math类,其重要方法有:

  • abs() :获取绝对值函数.
  • acos()、asin():反余弦、反正弦函数(以弧度为参数值PI结合运算).
  • cbrt():立方根函数.
  • cos()、sin():三角余弦、三角正弦函数(以弧度为参数值PI结合运算).
  • max()、min():获取两个数值中的最大值或最小值.
  • log()、log10():对数.
  • random():获取随机数.[0,1)
    注:Random类亦可实现,可根据种子创建随机数
  • round():四舍五入(获得整形值).
  • floor():得到小于该数的最小整数.
  • ceil():得到大于该数的最大整数.
  • sqrt():平方根.

字符串类

  • String:不需要通过new就可以直接创建String对象;+运算符可以用来拼接String内容,String一旦被赋值不能改变,值放在方法区字符串常量池中
    方法:

    • substring():返回子字符串
    • charAt():返回索引值位置的字符
    • startsWith():字符串是否由指定字符开头.
    • endsWith():字符串是否由指定字符结尾.
    • indexOf():返回子串在父串中第一次出现的下标(从左起).
    • lastIndexOf():返回子串在父串最后一次出现的下标(从右起).
    • split():按特殊字符拆分字符内容
    • replace():用新字符串内容,替换父串中原有的字符串内容.
    • replaceAll():使用给定replacement替换此字符串所有匹配给定的正则表达式的字符串
    • trim():去除字符串两端空格
    • matches():字符验证方法,告知此字符串是否匹配给定的正则表达式
    • getBytes():将字符串转为Byte[]数组
    • toCharArray():将字符串转为Char[]数组
    • valueof():将某数据类型转为字符串类型
    • toLowerCase()/toUpperCase():将字符串转换为大小写
    • concat():字符串拼接,将两个字符串连接起来
    • compareTo():按字典顺序比较两个字符串,返回字符串长度差
    • format():使用指定的语言环境、格式字符串和参数返回一个格式化字符串。

      转换符 说明
      %s 字符串类型
      %c 字符类型
      %b 布尔类型
      %d 整数类型(十进制)
      %x 整数类型(十六进制)
      %o 整数类型(八进制)
      %f 浮点类型,如%.2f指保留两位小数
      %e 指数类型
      %a 十六进制浮点类型
      %n 换行符
  • StringBuffer:对于内容变动较大的字符串内容处理能力较好(线程安全,数据同步),无参构造方法初始默认容量16个字符
    常用方法:append()、delete()、insert()
    与String的区别:String类在有新内容追加时,是结合原有字符串内容创建新的字符串对象(性能较低),使用StringBuffer拼接字符串不会浪费太多资源
    与数组的区别:都可以看做是一个容器,装其他数据;但StringBuffer数据最终是字符串数据,数组可放置多类同种数据

  • StringBuilder:单线程优先选用,速度快但不安全(JDK1.5)
    常用方法:append()、delete()、insert()
    注意:StringBuffer和StringBuilder为可变字符串类型:其字符内容可以灵活变动(追加、删除、插入)

正则表达式

由一组通用的特殊字符所组成的一套字符串内容验证规则,String通过matchs()方法来使用正则表达式验证字符串内容是否合要求.
通过Pattern/Matcher类使用正则表达式:先实例化一个Pattern类,得到的模式对象通过compile方法将给定表达式编译到模式中,通过模式对象matcher方法得到匹配器matcher,匹配器matches方法匹配给定输入

  • 语法-边界匹配器
    • ^:行的开头,代表一个正则表达式的开始.
    • $:行的结尾,代表一个正则表达式的结束.
    • \b:标识某一个单词的开头或结尾.
  • 字符
    • [abc]:a或b或c的任意一个.
    • [^abc]:除a、b、c以外的任意字符.
    • [a-zA-Z]:所有字母(大小都包括).
    • [a-d[m-p]]:a到d或m到p([m-p]将该内容作为整体)
    • [a-z&&[def]]:a-z和def两个表达式都满足.
    • [a-z&&[^bc]]、[a-z&&[^m-p]]
    • [0-9]
  • 预定义字符:
    • .:代表任意字符.
    • \d:字符内容只能是[0-9]的数字.
    • \s:空白字符.
    • \w:所有字符大小写、下划线、数字([a-zA-Z_0-9])
    • 反向字符:\D、\S、\W
  • 数量词
    • ?:一次或一次也没有.
    • *:零次或多次.
    • +:一次或多次.
    • {n}:n代表一定要出现的次数
    • {n,}:至少出现n次
    • {n,m}:n<=出现次数<=m.
  • 拓展
    零宽断言\捕获-是使用正则表达式来获取字符串中对应内容的所在位置.(不能结合String的matchs方法),而应该结合String的replaceAll、replaceFirst方法使用,用来找到替换需要替换的内容)。语法:

    • (?=exp):若字符串中有内容的结尾与exp匹配,则满足该断言.
    • (?<=exp):若字符串中的内容的开头与exp匹配,则满足该断言.
    • (?!=exp):若字符中的内容的结尾与exp不匹配,则满足该断言.
    • (?<!exp):若字符串的内容的开头与exp不匹配,则满足该断言.

其他程序的调用类

  • Runtime
    作用:获取java虚拟机的运行信息(可使用的CPU数量、所分配的内存大小、空闲内存).
    特点:一个虚拟机环境内有且仅有一个Runtime对象.
    方法:

    • static getRuntime():获取虚拟机对应的运行时信息.
    • static exec(String):启动子进程.
  • Process
    用于描述被JVM启动的一个子进程信息,可以通过Process让java代码与子进程通信.

java.util包

日期或时间类型

  • Date
    Java平台用于描述时间信息(包括用于精确描述年、月、日、小时、分钟、毫秒信息)的基类

    • after\before:日期比较方法.
    • getTime():获取日期信息的long格式值.
    • setTime(long):根据日期的long值,重新设置日期的时间点.
    • format格式:
      字母 日期或时间元素 表示 示例
      G Era 标志符 Text AD
      y 年 Year 1996; 96
      M 年中的月份 Month July; Jul; 07
      w 年中的周数 Number 27
      W 月份中的周数 Number 2
      D 年中的天数 Number 189
      d 月份中的天数 Number 10
      F 月份中的星期 Number 2
      E 星期中的天数 Text Tuesday; Tue
      a Am/pm 标记 Text PM
      H 一天中的小时数(0-23) Number 0
      k 一天中的小时数(1-24) Number 24
      K am/pm 中的小时数(0-11) Number 0
      h am/pm 中的小时数(1-12) Number 12
      m 小时中的分钟数 Number 30
      s 分钟中的秒数 Number 55
      S 毫秒数 Number 978
      z 时区 General time zone Pacific Standard Time; PST; GMT-08:00
      Z 时区 RFC 822 time zone -0800
  • Calendar
    基于通用日历规则,提供了日期运算方法

    • set(int,int):向对应的日期级别设置(第一个参数用于日期级别).
    • get(int):通过日期级别常量,获取当前日期的相关信息.
    • getDisplayName(int,int,locale):按指定格式和区域语言习惯,来返回日期的描述内容(中文只对月份、星期有效).
    • getFirstDayOfWeek():返回当前日期对象一周的第一天是星期几(默认1==星期天).
    • static getInstance():构造日历对象实例.
    • getTime():将日历对象转换成Date类型.
    • setTime():将date类型转换为日历类型.
    • getTimeInMillis():将日历类型转换了long格式的数据.
    • setTimeInMillis(long):将long格式的日期类型转换成日历类型.
    • add(int,int):可以在指定的日期级别上,对日期信息进行向前或者向后滚动(第二个参数正数向后增长,负数向前增长)

基于经典数据结构的集合框架

集合对象:弥补传统的数组在批量数据存储中和访问上的不足,提供一组基于经典数据结构,并提供了对应操作方法的API来满足编程开发中对批量数据的操作要求

集合、数组区别:①长度区别,数组长度固定,集合可变 ②内容不同,数组存储同种类型元素,集合可存储不同类型元素 ③集合只能存储引用类型

  • Iterable(接口):超级接口,JDK1.5以后加入的API,为集合框架满足foreach语句提供类型的定义.

    • 方法
      • iterator():基于集合内容,生成迭代器(可以提供方法依次访问集合中的对象)
  • Collection(接口):JDK平台上,所有集合框架的根接口,是用于存储多个对象(数据)的集合类型,数据可以是任何合法类型,可以有各种存储验证(是否为空,是否重复,是否有序);

    • 方法
      • add(Objectobj):向集合追加新的对象
      • addAll(Collection colletion):将另一个集合的内容,追加到当前集合内.
      • contains(Object c):判断对象是否为集合的成员.
      • containsAll(Collections c):判断两个集合是否存在包含情况.
      • Iterator():将集合内的数据转换为迭代器的格式来存储,迭代器便于按顺序访问集合内的元素.
      • retainAll(Collection c):留下两个集合都包含的元素.
      • size():集合中元素的个数.
      • toArray():将集合对象的内容装换为对象数组.
  • List(接口):有序的集合(存储和取出的元素一致)
    特点:通常允许重复的元素,允许null元素,有序,对应元素都有下标来标识,没有长度限制,可以自动的根据需要改变长度.

    • 方法
      • get(int index):通过下标获取集合列表中的某一个元素.
      • set(int index,E element):List特有方法,向列表中的指定项中设置元素(若原下标位置有值,则会替换).
      • subList(int fromIndex,int toIndex):截取集合列表中的一部分生成新的列表对象.
      • listIterator(int index):从指定位置开始调用迭代器
    • 实现类
      • ArrayList
        特点:底层基于数组来实现列表的功能,内部用于存储数据的结构是一个Object
        建议:其ArrayList的初始化大小,尽可能根据实际操作数据的大小来设定(避免因数组增长导致效率低下的问题).不善于对内容变动较大的集合数据提供存储。
      • LinkedList
        特点:底层基于链表的结构来实现存储功能.(链表是非常灵活的顺序存储结构,基于指针,将数据相互串联起来)。
        建议:在数据经常需要进行修改的情况下使用.若只需要对数据进行查询、获取等操作,则效率比不上ArrayList。
      • Vector
        特点:是线程安全的API(让多个同时执行线程有序的访问Vector中的数据,但会消耗相对应的内存)。
        建议:一般不采用。ArrayList可通过Collections.synchronizeList(List list)修改为线程安全的List
      • List子类区别
        • 类名 特点
          ArrayList 底层数据结构是数组,查询快,增删慢
          线程不安全,效率高
          Vector 底层数据结构是数组,查询快,增删慢
          线程安全,效率低
          LinkedList 底层数据结构是链表,查询慢,增删快
          线程不安全,效率高
  • Set(接口):不包含重复元素的集合
    特点:不允许有重复元素,最多包含一个null元素,不一定是有序存储。

    • 方法
      • Collection接口上定义的方法、add()、addAll()、iterator()、remove()
    • 实现类
      • HashSet:实现基于Hash表来维护数据,不保证数据的顺序不变,但可以保证数据的唯一性。(保存数据:通过Hash表来保存数据,但不会保存重复的数据,依赖hashCode()和equals()方法保证唯一性,必要时需要重写)
      • TreeSet:按照二叉树的结果来存放数据,保证数据的顺序;采用红黑树(二叉树):小的值放在左节点,大的值放在右节点.获取数据时,采用中序访问节点,将数据内容按大小排列比大小:使用对象的compareTo()方法比较两个对象的大小由TreeSet保存的对象,提供对Compareble接口的实现,并给出compareTo方法的实现。
        • 自然排序:让元素所属类实现Comparable接口
        • 比较器排序:让集合构造方法接收Comparator的实现类对象
      • LinkedHashSet
        特点:底层数据结构由哈希表和链表组成。基于Hash表来存放数据,保证数据唯一性;链表会对数据的插入顺序进行维护,按照数据放入Set集合的顺序给输出来,将对象在hash表中的hash值,按插入顺序保存在链表中,在生成的Iterator时,根据链表的结构一次访问获取对象,操作性能较低,在大数据量的集合操作上不建议使用。
  • Iterator :将数据有序的组织在一起,并提供按序访问的方法
    • 方法
      • hasNext():判断迭代器是否还有遍历到的元素
      • next():可以得到向下遍历的对象.(迭代器使用时不能对其内值进行删除操作,程序会报错)
  • Map :基于键-值映射的关系来搭建存储结构,在整个结构中使用key值来唯一标识对象.(在JDK1.2之后出现用于替换原有API中的Dictionary类的作用)。

    • 常用方法
      • put(key,value)
      • get(key)
      • remove()
      • values():将结构中存储的所有值都以对象的形式返回
      • keySet():将结构中的所有key值,以set结构返回.
    • 实现类

      • HashMap:基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。键唯一,值覆盖。

      HashMap与Hashtable区别:Hashtable线程安全效率低,不允许null键和null值;HashMap线程不安全效率高,允许null键和null值。

      • TreeMap: –底层基于二叉树结构来存储数据,会根据key来作为二叉树的节点关键属性来进行排序操作,按key值的从小到大进行排列
  • Dictionary –也是基于键-值结构,但已经过期。
    • 实现类
      • HashTable:基于哈希表实现键值对应,是一个线程安全的同步的API。不可以接受为null的key和value
      • Properties:属性集合类,结合IO流使用(使用load()、store()方法、getProperty()方法),可保存在流或在流中加载,提供一个属性信息的键值对存储结果,可以与*.properties文件使用(key:属性名;value:属性值).
  • Collections:定义了多种操作集合对象的方法(查找、插入、排序等方法)
    sort()、binarySearch()、copy()、max()、min()、reverse()

Scanner类

一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器

  • 常用方法
    • hasNextXxx():Xxx表示数据类型,判断是否还有下一个输入项,返回bool值
    • nextXxx():将下一个输入项扫描为一个Xxx

Arrays类

工具类,对数组进行操作,如排序、查找等

  • 常用方法
    • toString():合并数组转为字符串
    • sort():快速排序
    • binarySearch():二分查找
    • asList():返回一个受指定数组支持的固定大小的列表,与Collection.toArray()实现数组、collection的相互转换,返回列表是可序列化的,并且实现了RandomAccess
      注意:虽然可以把数组转换成集合,但是集合的长度不能改变,所有集合的部分方法无法使用,会报出UnsupportedOperationException

Collections类

工具类,完全由在 collection 上进行操作或返回 collection 的静态方法组成。

  • 常用方法
    • sort():排序,默认自然排序
    • binarySearch():二分查找
    • max():最大值
    • reverse():反转
    • shuffle():随机置换
    • synchronizedList(List list):返回线程安全的List集合,替代Vector

定时器类

定时器是一个应用十分广泛的线程工具,用于调度多个定时任务以后台线程的方式执行。在JAVA中,可以通过Timer和TimerTask类来实现定义调度的功能。

  • Timer类:管理一个过期的计时器通知列表,schedule()方法分配TimeTask及时间
  • TimerTask类:由 Timer 安排为一次执行或重复执行的任务。

java.io包

这个包下的api即java输入输出操作API,什么是输入输出操作?即向程序输入信息,向程序外部输出信息,数据被输入或者是输出的基础单位是字节byte
输入输出流按流的功能分可分为:

  • 低级流(节点流):自己具有流的写入或者读取能力的流.
  • 高级流(功能流):基于低级流的功能,实现流操作功能的扩张.

File类

文件和目录路径名的抽象表示形式。

  • 常用方法
    • createNewFile():返回Boolean值,创建文件,创建文件时不写盘符路径时,默认在Project目录下
    • mkdir():返回Boolean值,创建文件夹,目录下不存在该文件夹则完成创建并返回true,否则返回false
    • mkdirs():返回Boolean值,创建多级文件夹
    • delete():返回Boolean值,删除文件夹/文件,Java中删除不走回收站,删除文件夹时该文件夹下不能有文件和文件夹
    • renameTo(File dest):返回Boolean值,重命名方法,路径名相同相当于改名,路径名不同就是改名并剪切
    • 判断方法
      • isDirectroy() 判断是否是目录
      • isFile() 判断是否是文件
      • exists():判断是否存在
      • canRead/Write():判断是否可读、可写
      • isHidden():判断是否隐藏
    • 基本获取功能
      • getAbsolutePath():返回字符串,获取绝对路径
      • getPath():返回字符串,获取相对路径
      • getName():返回字符串,获取名称
      • length():返回Long类型,获取长度,表示字节数
      • lastModified():返回Long类型,获取最后一次修改时间,表示毫秒值
    • 高级获取功能
      • list():返回String数组,参数可传FilenameFilter过滤器过滤
      • listFiles():返回FIle类型数组,参数可传FilenameFilter过滤器过滤

字节流

  • InputStream(输入流) :表示字节输入流的所有类的超类
    常用方法有:

    • available() :获取总字节数,获取缓存区中的字节个数
    • close():负责释放IO资源,关闭流操作.
      为什么要关闭clos()?:A.让流对象变成垃圾,这样就可以被回收了 B.通知系统去释放跟该文件相关的资源
    • mark():在输入输出流的字节位置上设标记,为后面reset反复读取该段字节做准备.
    • reset():将流的操作重新定位
    • markSupported():用于判断mark方法或reset方法是否可用.
    • int read():用于读取一个字节信息:返回值是读取到的字节,若读到文件末尾,则返回-1.
    • int read(byte[] b):将字节读入到byte[]数组中:返回值是读取到的字节数,若读到文件末尾,则返回-1.(将字节读取到byte[]数组中第off位开始之后的位置,读取长度为len个字节)
  • OutputStream:表示输出字节流的所有类的超类,常用方法有:
    • close():关闭流
    • flush():将缓存中的字节,清空输出.
    • write(byte[] b):将字节数组中的内容输出
    • write(int b):将单个字节输出.
    • write(byte[] b,intoff,int len):将字节数组中从off开始的信息输出,共输出len个字节.
  • FileInputStream extends InputStream –(文件输入流)
  • FileOutputStreamextends OutputStream –(文件输出流),构造方法:FileOutputStream(Stringname,boolean append),其中append为ture时:追加内容到文件尾部.
  • FilterInputStream:输入过滤流,负责在其他流基础上扩展新的功能
  • FilterOutputStream:输出过滤流,负责在其他基础上扩展新的功能.
  • BufferedInputStream:为流操作提供字节缓存,减少直接申请的IO读取的次数;实现原理是在内存中创建了字节数组,缓存字节信息.
  • BufferedOutputStream :为流操作提供字节缓存,减少直接申请IO写出的次数.
  • DataInputStream:以java基本数据类型的格式读取信息.
  • DataOutputStream :以java基本数据类型的格式输出信息.
  • ObectInputStream:反序列号流,对象流输入,可以将流对象数据整体读入,还原为对象(注意:对象必须实现java.io.Serializable可序列化)
  • ObjectOutputStream:序列化流,对象流输出,可以将对象转换为流数据存入文本或在网络中传输,成员变量不需要序列化使用transient关键字声明
    注意:对象流使用的场景是大型数据的缓存,缓存一般会放在内存中。把数据量较大,且交互次数较低的数据放到文件中保存,再从文件中将数据还原内存;或者放在分布式系统(通过网络通信);如:发送远程调用的请求信息,远程调用的处理结果.

    • SequenceInputStream:继承于InputStream,可以将多个输入流串流在一起,合并为一个输入流,简称合并流。如需合并多个,构造方法内传Enumeration,可使用Vector集合添加。
  • 压缩流(基于字节流),API:java.util.zip.*包下的类,是封装基于ZIP标准进行无损压缩的API
    • ZipOutputStream:基于zip格式生成压缩文件,方法:putNextEntry(),closeEntry()
    • ZipInputStream:读取ZIP文件内容.可以理解wie解压缩.
    • ZipEntry:在压缩内容中代表一项压缩条目(压缩条目是一个独立的信息存储单元,一般用于将某一个文件的内容单独存储起来).

字符流

  • Reader:表示字符输入流的所有类的超类,常用方法有:read()、close()。
    • InputStreamReader:Reader子类,字符转换流,用默认或指定的编码读取数据
  • Writer:表示字符输出流的所有类的超类,常用方法有:write()、flush()、close()。
    close()、flush()区别:close关闭流对象,但是先刷新一次缓冲区;flush仅仅刷新缓冲区,刷新之后流对象可以继续使用

    • OutputStreamWriter:Writer子类,字符转换流,用默认或指定的编码写数据
  • BufferedReader/BufferedWriter:为流操作提供字符缓存,减少直接申请的IO读取/写入的次数。(使用BufferedWriter完成写操作时,补上BufferedWriter.flush())
  • 随机存取 RandomAccessFile
    • RandomAccessFile.seek(int):寻找文件位置
    • RandomAccessFile.write(bytes[]):在所在位置写数据
    • RandomAccessFile.read(bytes[]):在所在位置读数据

内存操作流

用于处理临时存储信息,程序结束,数据从内存中消失

  • 字节数组
    • ByteArrayInputStream:包含一个内部缓冲区,该缓冲区包含从流中读取的字节,关闭 ByteArrayInputStream 无效,此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。
    • ByteArrayOutputStream:此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException
  • 字符数组
    • CharArrayReader:此类实现一个可用作字符输入流的字符缓冲区
    • CharArrayWriter:此类实现一个可用作字符输出流的字符缓冲区,此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException
  • 字符串
    • StringReader:其源为一个字符串的字符流
    • StringWriter:一个字符流,可以用其回收在字符串缓冲区中的输出来构造字符串。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException

打印流

  • 特点
    • 只有写数据,没有读取数据,只能操作目的地,不能操作数据源
    • 可以操作任意类型数据
    • 如果启动了自动刷新,能够自动刷新(构造方法autoFlush参数设置true即可启用自动刷新)
    • 可以直接操作文本文件
  • PrintStream:字节流打印流,继承自OutputStream
    1. 标准输入输出流
    2. System类中的in/out,它们各代表了系统标准的输入输出设备,默认输入时键盘,默认输出是显示器
    3. System.in:类型是InputStream
    4. System.out:类型是PrintStream,是OutputStream的子类FilterOutputStream的子类
  • PrintWriter:字符打印流,继承自Writer

  1. 拓展:
  2. File :系统上一个文件资源,包括文件(*.txt、*.exe、*.doc等)和文件夹(用于组织和存放其他文件信息)
  3. 作用:
  4. 获取文件夹的子文件信息—listFile()
  5. 获取文件的属性,如getName() –获取文件的名字.
  6. 判断是否为文件目录—isDirectory()返回结果是ture为目录,false为其他内容.
  7. 判断是否为文件—isFile()返回结果是ture为文件,false为其他内容.还可以修改文件和删除文件.
  8. 设计模式,是指在编程的开发过程中,被反复论证所总结出来的编程经验.这些经验被认定为解决具体问题的最佳方案.
  9. 装饰模式:面向对象的常用模式之一.符合开关原则:原有代码不发生任何改变,而对原有代码进行扩展
  10. 结构:
  11. 目标类(FileInputStreamFileOutputStream等)。
  12. 装饰类(BufferdInputStreamBufferedOutStream等),与目标类都有相同的父类或接口。
  13. 用途:改进原有API的功能—修改原有的方法,丰富原有API的实现—能实现的功能更多。
  14. 最纯的装饰模式:目标类和装饰类从结构上一模一样(BufferedInputStream\BufferedOutputStream)。
  15. 装饰的”另类”:对类的结构做出调整,如ObjectInputStream\ObjectOutputStream(readObject()\writeObject() )和DataInputStream\DataOutputStream( readXXX()\writeXXX() )。

GUI

java.awt包

属于java基本包,Abstract Window ToolKit,抽象窗口工具包,需要调用本地系统方法实现功能,属于重量级控件。

  • MenuComponent类:抽象类 MenuComponent 是所有与菜单相关的组件的超类。在这一方面,类 MenuComponent 与 AWT 组件的抽象超类 Component 相似。菜单组件接收并处理 AWT 事件,就像组件通过方法 processEvent 执行的操作一样。

    • Menu:Menu 对象是从菜单栏部署的下拉式菜单组件。
    • MenuBar:MenuBar 类封装绑定到框架的菜单栏的平台概念。为了将该菜单栏与 Frame 对象关联,可以调用该框架的 setMenuBar 方法。
    • MenuItem:菜单中的所有项必须属于类 MenuItem 或其子类之一。 默认的 MenuItem 对象包含一个简单的加标签的菜单项。
  • Component类:component 是一个具有图形表示能力的对象,可在屏幕上显示,并可与用户进行交互。典型图形用户界面中的按钮、复选框和滚动条都是组件示例。
    直接已知子类:Button, Canvas, Checkbox, Choice, Container, Label, List, Scrollbar, TextComponent

    • Container类
      • setLayout():设置布局,常见layout有FlowLayout、GridLayout、BorderLayout、CardLayout、GridBagLayout等。
    • Frame类:窗体框架
      • setVisible:设置窗体可见
      • setSize:设置窗体大小(参数可传Dimension类对象,设置窗体大小)
      • setLocation:设置窗体位置(参数可传Point类对象,设置窗体中心坐标)
      • setTitle:设置窗体标题
      • setBounds:相当于setSize、setLocation方法的结合
      • addWindowListener:接收窗口的监听接口,传入WindowListener接口,如想实现适配器模式,可传WindowAdapter方法
    • Button类:按钮类
      • addActionListener:接收按钮的监听接口
      • TextField类:文本域类,TextField 对象是允许编辑单行文本的文本组件。
      • TextArea类:文本区类,TextArea 对象是显示文本的多行区域。可以将它设置为允许编辑或只读。

javax.swing包

属于扩展包,AWT的基础上建立的一套图形界面系统,其中提供了更多组件且完全由java实现,属于轻量级控件。

  • 容器:用来存放按钮、输入框等组件
    • JFrame:JFrame是最常用的窗体型容器,默认情况下,在右上角有最大化最小化按钮
    • JDialog:JDialog也是窗体型容器,右上角没有最大和最小化按钮
  • 布局器:布局器是用在容器上的。 用来决定容器上的组件摆放的位置和大小。setLayout设置为null时为绝对定位。
    • FlowLayout:容器上的组件水平摆放,加入到容器即可,无需单独指定大小和位置
    • BorderLayout:容器上的组件按照上北 下南 左西 右东 中的顺序摆放
    • GridLayout:网格布局,容器组件按方格划分,指定行列数
    • CardLayout:下拉框布局
    • setPreferredSize:即便 使用 布局器 ,也可以 通过setPreferredSize,向布局器建议该组件显示的大小
  • 组件:JAVA的图形界面下有两组控件,一组是awt,一组是swing。一般都是使用swing。通用方法setBounds(int x,int y,int width,int height)可设置窗口位置、大小。
    • JLabel:标签,Label用于显示文字
    • setIcon:使用JLabel显示图片
    • JButton:按钮
    • JCheckBox:复选框,使用isSelected来获取是否选中
    • JRadioButton:单选框,使用isSelected来获取是否选中
    • ButtonGroup:按钮组,ButtonGroup 对按钮进行分组,把不同的按钮,放在同一个分组里 ,同一时间,只有一个 按钮会被选中
    • JComboBox:下拉框,JComboBox 下拉框,使用getSelectedItem来获取被选中项,使用setSelectedItem() 来指定要选中项
    • JOptionPane:对话框,用于弹出对话框。showMessageDialog()可弹出对话框
    • JTextField:文本框,setText 设置文本,getText 获取文本,JTextField 是单行文本框,如果要输入多行数据,请使用JTextArea
    • JPasswordField:密码框,与文本框不同,获取密码框里的内容,推荐使用getPassword,该方法会返回一个字符数组,而非字符串
    • JTextArea:文本域,文本域可以输入多行数据,如果要给文本域初始文本,通过\n来实现换行效果,JTextArea通常会用到append来进行数据追加,如果文本太长,会跑出去,可以通过setLineWrap(true) 来做到自动换行
    • JProgressBar:进度条
    • JFileChooser:文件选择器,使用FileFilter过滤文件格式等
  • 面板:JPanel即为基本面板 ,面板和JFrame一样都是容器,不过面板一般用来充当中间容器,把组件放在面板上,然后再把面板放在窗体上。一旦移动一个面板,其上面的组件,就会全部统一跟着移动,采用这种方式,便于进行整体界面的设计
    • ContentPanel:JFrame上有一层面板,叫做ContentPanel 。平时通过add()向JFrame增加组件,其实是向JFrame上的 ContentPanel加东西
    • SplitPanel:创建一个水平JSplitPane,左边是pLeft,右边是pRight
    • JScrollPane:带滚动条的面板
    • TabbedPanel:带标签的面板,通过add()添加组件,setTitleAt()方法设置组件标签
  • 线程
    • 初始化线程
      初始化线程用于创建各种容器,组件并显示他们,一旦创建并显示,初始化线程的任务就结束了。
    • 事件调度线程
      时间调度线程是单线程的,因为 Swing里面的各种组件类,比如JTextField,JButton 都不是线程安全的,这就意味着,如果有多个线程,那么同一个JTextField的setText方法,可能会被多个线程同时调用,这会导致同步问题以及错误数据的发生。

      • SwingUtilities.invokeLater():请求事件分发线程以运行某段代码
      • SwingUtilities.invokeAndWait():直到事件分发线程已经执行了指定代码才返回
      • SwingUtilities.isEventDispatchThread():判断当前线程是否是事件调度线程
    • 长耗时任务线程
      有时候需要进行一些长时间的操作,比如访问数据库,文件复制,连接网络,统计文件总数等等。 这些操作一般都会在事件响应后发起,就会自动进入事件调度线程。 而事件调度线程又是单线程模式,其结果就会是在执行这些长耗时任务的时候,界面就无响应了。为了解决这个问题,Swing提供了一个SwingWorker类来解决。

      • SwingWorker类:SwingWorker 设计用于需要在后台线程中运行长时间运行任务的情况,并可在完成后或者在处理过程中向 UI 提供更新。SwingWorker 的子类必须实现 doInBackground() 方法,以执行后台计算。

java.net包

  • InetAddress类:此类表示互联网协议 (IP) 地址。(类 Inet4Address为IPv4地址格式,类 Inet6Address为IPv6地址格式)
  • Socket类:是TCP客户端API。Socket:网络套接字,Socket包含了IP地址+端口,网络通信其实就是Socket间的通信,数据在两个Socket间通过某种协议使用IO流传输
  • ServerSocket类:是 TCP 服务器 API。通常接受 (java.net.ServerSocket.accept) 源于客户端套接字的连接。
  • DatagramSocket类:是 UDP 端点 API。此类表示用来发送和接收数据报包的套接字,可发送数据报包DatagramPacket,启用UDP广播发送。
  • DatagramPacket类:数据报包,用来实现无连接包投递服务。DatagramPacket 包含的信息指示:将要发送的数据、其长度、远程主机的 IP 地址和远程主机的端口号。

Java学习笔记

Java

  • 1.1995年推出Java程序设计语言和Java平台(即JavaEE JavaME JavaSE)

  • 2.流行的Java开发环境:
    (1)Eclipse (2)Myeclipse (3)IntelliJIDEA (4)Jbuider (5)Jdeveloper (6)Netbeans (7)JCreator

  • 3.Java 虚拟机:称为JVM(Java Virtual Machine),Java运行环境又称为JRE(Java Runtime Environment)

  • 4.Eclipse是一个开放源代码、基于Java的可扩展开发平台,只是一个框架和一组服务,用于通过插件组件构建开发环境。附带标准插件集,包括Java开发工具(Java Development Kit,JDK)

  • 5.建立资源包要遵循MVC 结构规则(Model View Controller)


知识点

变量

  • char、short、byte不能相互转换,在运算时会自动转为int类型,由于JVM机制,此类变量无法直接相加
  • char/short/byte<int<long<float<double,小值转大值无需强制类型转换
  • 二进制自变量前加0b或0B可自动转为整形,数字可用”_”分割方便阅读(JDK7新特性)
  • 静态变量与成员变量区别
    • 静态变量属于类,也称类变量,成员变量属于对象,也称实例变量
    • 静态变量存储在方法区中的静态区,成员变量存储在堆内存中
    • 静态变量随类加载而加载,随着类消失而消失。成员变量随着对象创建而存在,随着对象消失而消失
    • 静态变量可以通过类名调用,成员变量只能通过对象名调用

  • 初始化过程
    • 属性、方法、构造方法和自由块都是类中的成员,在创建类的对象时,类中各成员的执行顺序:
      • 1.父类静态成员和静态初始化快,按在代码中出现的顺序依次执行。
      • 2.子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。
      • 3.父类的实例成员和实例初始化块,按在代码中出现的顺序依次执行。
      • 4.执行父类的构造方法。
      • 5.子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。
      • 6.执行子类的构造方法。
    • 分层初始化:先进行父类初始化,然后进行子类初始化。super()仅仅表示要先初始化父类数据,再初始化子类数据
  • Object类
    Object类是类层次结构的根类,所有类都直接或间接继承自该类

    • hashCode()
      返回对象的哈希码值,根据对象实际地址通过哈希算法得出,int类型。主要作用为提高哈希表性能。
    • getClass()
      返回此 Object 的运行时类,即字节码文件对象
    • toString()
      返回该对象的字符串表示,等同于 getClass().getName() + ‘@’ + Integer.toHexString(hashCode()),易读性较差,一般需要重写toString方法
    • equals(Object obj)
      默认判断对象地址值是否相等,注意当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
    • finalize()
      用于垃圾回收,System.gc()调用时finalize方法执行,当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类重写 finalize 方法,以配置系统资源或执行其他清除
    • clone()
      创建并返回此对象的一个副本,开辟新内存空间,非引用原地址。重写clone方法时,被克隆的类需实现Cloneable接口,否则会抛出CloneNotSupportedException异常
    • notify()
      唤醒在此对象监视器上等待的单个线程,唤醒不代表立即执行,依然要抢CPU执行权
    • notifyAll()
      唤醒在此对象上等待的所有线程
    • wait()
      线程等待,notify后从此行开始继续向下执行代码

枚举

枚举允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示。定义枚举类要用关键字enum,所有枚举类都是Enum的子类。
注意:枚举类可以有构造器,但必须private;枚举类也可以有构造方法,但是枚举项必须重写该方法。

  • 格式
  1. 访问修饰符 enum 枚举名称
  2. {
  3. 枚举1,枚举2,枚举3,枚举4...枚举n //枚举序数依次为0/1/2/3....n-1
  4. }
  • 常用方法
    • ordinal:返回枚举序数
    • valueOf:返回指定名称、指定类型的枚举常量
    • name:返回枚举常量名称
    • compareTo:返回枚举序数的差值

位运算符

  • <<:空位补0,被移除的高位丢弃
  • >>:高位被移后,最高位符号不变
  • >>>:被移位二进制最高位强制用0补
  • &:二进制数按位进行与运算
  • |:二进制数按位进行或运算
  • ~:二进制数按位进行非运算(得到的数是补码)
  • ^:二进制数按位进行抑或运算(a^b^a,结果是b)

修饰符

  • 权限修饰符
位置 public protected default private
同一类中
同一包子类,无关类 ×
不同包子类 × ×
不同包无关类 × × ×
  • 类及其组成可用修饰符
    • 类:default,public,final,abstract (自定义public居多)
    • 成员变量:四种权限修饰符,final,static (自定义private居多)
    • 构造方法:四种权限修饰符 (自定义public居多)
    • 成员方法:四种权限修饰符,final,static,abstract (自定义public居多)

代码块

JAVA中用{}括起来的代码称为代码块,根据其位置不同可分为:

  • 局部代码块:局部位置,方法中出现,用于限定变量的生命周期,及早释放,提高内存利用率
  • 构造代码块:在类的成员位置,多个构造方法中相同代码存放在一起,每次调用构造都执行,并且在构造方法前执行
  • 静态代码块:近似于构造代码块,{前加static修饰,一般用于对类进行初始化
  • 同步代码块:synchronize(锁对象){….},用于实现多线程线程安全

异常

超类Throwable,程序异常分为Error、编译期异常和运行期异常(RuntimeException)。

  • Java异常分类
    • ①Error: 这种异常被设计成不被捕获,因为这种异常产生于JVM自身。
    • ②Runtime Exception: 运行时异常往往与环境有关,编译时无法检查,并且可能发生的情况太广泛,所以系统会去处理,程序不需要捕获。
    • ③普通异常(编译期异常): 常见的异常大多属于此类。
  • 常见异常
    • ArrayIndexOutOfBoundsException:数组索引越界异常
    • NullPointerException:空指针异常
    • ClassCastException:类转换异常(易出现于多态向下转型中)
    • CloneNotSupportedException:对象不支持克隆异常
    • ArithmeticException:算术异常
  • 处理方法

    • try…catch…finally:捕获异常,后续程序需要继续运行时使用。try里面的代码越精简越好,以免JVM浪费过多资源处理;catch内必须有内容,能明确的异常尽量明确,如果出现异常父子关系,父在后。
      1. try{
      2. 可能出现问题的代码;
      3. }catch(异常名1|异常名2|...|异常名n 变量){ //多个异常处理时,处理方法是一致的,而且多个异常间必须是平级关系(JDK7新特性)
      4. 针对问题的处理; //如果内有return语句,finally内部代码在return前执行
      5. }finall{ //finally控制的语句体一定会执行,用于释放资源,多见于IO流
      6. 释放资源;
      7. }
    • try-with-resources:java7新特性,这种在try后面加个括号,再初始化对象的语法就叫try-with-resources。判断对象是否为null,如果不为null,则调用close()函数的的字节码。
      注意:只有实现了java.lang.AutoCloseable接口,或者java.io.Closable(实际上继随自java.lang.AutoCloseable)接口的对象,才会自动调用其close()函数。

      1. try(实例化类1;实例化类2...){
      2. ...
      3. }catch(...){
      4. ...
      5. }finally{
      6. ...
      7. }
    • throws:抛出异常,后续程序不需要继续运行时使用。定义功能方法时,需要把问题抛出交由调用者处理,则通过throws在方法上标识

      1. throws 异常类名 //必须跟在方法的括号后面
throws和throw区别 区别
throws 用在方法声明后面,跟的是异常类名;
可以跟多个异常类名,用逗号隔开;
表示抛出异常,由该方法调用者处理;
throws表示出现异常的一种可能性,并不一定会发生
throw 用在方法内,跟的是异常对象名;
只能抛出一个异常对象名;
表示抛出异常,由方法体内的语句处理;
throw是抛出了异常,执行throw则一定抛出了某种异常
名称 区别
final 关键字,修饰类=>不能被继承、修饰变量=>常量、修饰方法=>不能被重写
finally 异常处理的一部分,被用于释放资源
finalize Object类的一个方法,用于垃圾回收
  • 常用方法
    • getMessage():异常的消息字符串
    • toString():返回异常的简单信息描述
    • printStackTrace():默认catch方法,将此 throwable 及其追踪输出至标准错误流。此方法将此 Throwable 对象的堆栈跟踪输出至错误输出流,作为字段 System.err 的值
  • 自定义异常
    • 自己想定义一个异常类,编译期异常需要继承自Exception、运行期异常继承自RuntimeException,注意重写父类异常构造方法
  • 注意事项
    • 子类重写父类方法时,子类方法必须抛出相同的异常或父类异常的子类
    • 如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是它的子集,子类不能抛出父类没有的异常
    • 如果被重写的方法没有抛出异常,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,只能try..catch…

方法

  • 构造方法
    与类名一致,创建对象时调用构造方法,可重载。子类无条件继承父类不带参数的构造方法,调用其他构造方法必须使用super关键字,子类不能重写父类构造方法。
  • 重写与重载
    Overloading与Overriding,重载发生在一个类中,重写发生在继承中
    构造方法用private修饰,即可实现单例模式,即该类无法创建对象,只能通过类调用static方法

    • 方法重载:同一个类中,出现的方法名相同、参数列表不同的方法,重载可以改变返回值类型,因为它和返回值无关
    • 方法重写:子类中出现的和父类一模一样的方法声明
      • 使用特点
        • 如果方法名不同,有就调用对应的方法
        • 如果方法名相同,最终使用的是子类自己的
      • 应用
        • 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样既沿袭了父类的功能,又定义了子类特有的内容
      • 注意事项
        • 父类中私有方法不能被重写
        • 子类重写父类方法时,访问权限不能更低
        • 父类静态方法,子类也必须通过静态方法重写
  • 形式参数
    形式参数paramet,实际参数argument

    • 可变参数:当参数个数不确定时,可设置可变参数,最多设置一个。可变参数只能放置在参数的最后,即最右。编译器将可变参数当做一维数组对待,可使用foreach语句调用。
      格式例如:public void Function1(String str,String...arr){} // public void Function2(String...arr){}

内存分配

  • 栈:存储局部变量,创建类存储在栈内存,栈内存指向堆内存
  • 堆:存储成员变量,实例化对象开辟内存空间、存储在堆内存中(new出来的内容)
  • 方法区:
    • 静态域:存放在对象中用static定义的静态成员,堆栈具有动态特性。
    • class内容区域:存放类的定义,包含类内部的成员变量和成员方法的定义
    • 方法内容区域:存放构造方法和类内部方法
  • 本地方法区:和系统相关
  • 寄存器:给CPU使用

抽象类

  • 包含一个抽象方法的类就是抽象类,声明而未被实现的方法称为抽象方法,用abstract关键字声明。
  • 抽象类被子类继承,子类(如果不是抽象类)必须重写抽象类中的所有抽象方法。
  • 抽象类不能直接实例化,要通过其子类进行实例化。
  • 抽象类关键字abstract与private、final冲突,static无意义
    • 定义格式:
      1. abstract class className [extends 继承父类]
      2. {
      3. 属性;
      4. 方法;
      5. 抽象方法;
      6. }

接口

  • 接口是一种特殊的类,里面全部是由全局常量和公共的抽象方法组成。(成员变量默认修饰符:public static final,成员方法默认修饰符:public abstract)JDK8允许接口内使用default关键字和static关键字修饰方法并给出方法体,为接口添加非抽象的或静态的方法

  • 接口无构造方法(事实上调用接口时,extends Object类,子类默认重写Object无参构造方法//注:Object类是类层次结构的根类,每个类都使用Object类作为超类)

  • 接口实现必须通过子类,使用关键字implements,而且接口是可以多实现的。
  • 一个子类可以同时继承抽象类和实现接口。
  • 一个接口不能继承一个抽象类,但是却可以通过extends关键字同时继承多个接口,实现接口的多继承。
    • 接口格式:
      1. interface interfaceName [implements 继承接口]
      2. {
      3. 全局常量;
      4. 抽象方法;
      5. }
  • 抽象类与接口的区别
区别 成员区别 关系区别 设计理念区别
抽象类 成员变量可以是常量,也可以是变量
有构造方法
成员方法可以抽象,也可以非抽象
类与类:继承,单继承 被继承体现的是“is A”的关系
定义该继承体系的共性功能
接口 成员变量只能是常量
无构造方法
成员方法只能是抽象
类与接口:实现,单实现,多实现
接口与接口:继承,单继承,多继承
被实现体现的是“like A”的关系
定义该继承体系的扩展功能

OOP特性

封装性

  • 类下面属性使用private等关键字封装,通过使用属性调用(快速方法:右键Source→Generate Setter&Getter)
  • 匿名对象使用:程序只用一次该对象,可利用匿名对象的方式,无需实例化,直接new调用。有利于GC(garbage collection垃圾回收)

继承性

  • Java内使用extends关键字继承已有类。
  • Java中只允许单继承(可以多层继承),子类无法访问父类私有成员,只能继承父类所有非私有的成员方法和成员变量
  • 子类调用构造方法之前,先调用父类中的无参构造方法
  • 子类不能继承父类的构造方法,父类无无参构造方法不能调用,可利用super关键字调用父类方法(super代表父类存储空间的标识),可利用this调用本类其他构造方法
  • 注意事项:super、this调用构造方法时必须置于第一行
  • 方法重写:子类定义与父类同名的方法。定义:方法名称相同,返回值类型相同,参数也相同。限制:子类重写父类方法时,访问权限不能低于父类权限(private<default<public),权限最好一致
  • 继承优缺点:
    • 优点
      • 提高代码复用性,多个类相同的成员可以放到同一个类中
      • 提高代码维护性,如果功能的代码需要修改,修改一处即可
      • 类与类之间产生关系,是多态的前提(同时也是弊端:类的耦合性变强)
    • 缺点
      • 开发的原则在于低耦合、高内聚,尽可能单独处理任务

多态性

  • 实现:方法的重载和重写、对象的多态性。
  • 对象的多态性:
    • 向上转型:程序自动完成(父类 父类对象=子类实例
    • 向下转型:强制类型转换(子类 子类对象=(子类)父类实例)
  • 前提:要有继承关系,要有方法重写,要有父类引用指向子类对象。
  • 多态中的成员访问特点
    • 成员变量:编译看左边,运行看左边
    • 构造方法:创建子类对象时,访问父类构造方法,对父类数据进行初始化
    • 成员方法:编译看左边,运行看右边(成员方法由于重写,运行看右边)
    • 静态方法:编译看左边,运行看左边(静态和类相关,算不上重写)

内部类

把类定义在其他类的内部,这个类就是内部类

  • 内部类的访问特点
    • 内部类可以直接访问外部类成员,包括私有
    • 外部类要访问内部类成员,必须创建对象
    • 内部类和外部类没有继承关系,内部类如想调用外部类成员,需通过外部类名限定this对象(即通过外部类名.this.成员变量调用)
  • 内部类划分
    • 根据位置划分
      • 成员内部类:定义在成员位置
        创建对象:外部类名.内部类名 对象名=new 外部类对象.new 内部类对象
      • 局部内部类:也叫方法内部类,定义在局部位置,可直接访问外部类成员,通过调用内部类方法来使用局部内部类功能
        局部内部类访问局部变量必须被final修饰,因为局部变量会随着方法调用完毕而消失,而堆内存内容并不会立即消失,final修饰后变量变为常量
  • 静态内部类
    用static将内部类静态化,内部类只能访问外部类的静态成员变量。
    内部类被静态化,可以看做是外部类的成员,因此内部外部可以当做一个整体看,可以直接new 出内部类的对象(通过类名访问static,生不生成外部类对象都没关系)
    创建对象:外部类名.内部类名 对象名=new 外部类名.内部类名
  • 私有内部类
    如果一个内部类只希望被外部类中的方法操作,那么可以使用private声明内部类。
  • 匿名内部类
    即内部类的简化写法

    • 前提:存在一个类或者接口
    • 格式:new 类名或接口名(){重写方法;};
    • 本质:是一个继承了类或者实现了接口的子类匿名对象
    • 应用:无需实例化新的对象,只能用一次,便于内存回收
  • Lambda表达式
    • 介绍:与匿名类概念相比较,Lambda 其实就是匿名方法,是一种把方法作为参数进行传递的编程思想。匿名类型最大的问题就在于其冗余的语法
    • 语法:由参数列表、箭头符号->和函数体组成。函数体既可以是一个表达式,也可以是一个语句块。
      格式:(T args) -> { //代码块 }

      • 参数:(T args)是这个lambda expression的参数部分,包括参数类型和参数名,可为空,小括号不可缺少
      • 箭头:->,不可缺少
      • 代码块:就是用”{}”包含着的代码。当代码块内代码只有一行时,花括号可以省略,且代码块内分号省略

泛型(Generic)

  • 格式:
    1. 访问权限 class 类名<泛型,泛型...>
    2. {
    3. 属性;
    4. 方法;
    5. }
  • 实例化:
    类名<具体类型> 对象名=new 类名<具体类型> ();
    方法参数使用通配符“?”指定泛型。

    • 泛型接口:interface 接口名称<泛型标识>{……}

    • 泛型方法:访问权限 <泛型标识>泛型标识 方法名称([泛型标识 参数名称]){……}

多线程

线程:程序中单独顺序的控制流,本身依靠程序运行,只能分配给程序的资源和环境
进程:执行中的程序,一个进程可以包含一个或多个线程,至少要包含一个线程
单线程:程序中只存在一个线程,实际上主方法就是一个主线程
多线程:在一个程序中运行多个任务,更好使用CPU资源

  • ①线程实现方式:继承Thread类;实现Runnable接口
    • Thread类:在java.lang包中定义,继承Thread类必须重写run()方法
      • 定义格式:
        1. class ClassName extends Thread
        2. {
        3. run(){......}
        4. }
    • Runnable接口:同Thread,调用接口方式,同样需要覆写run()方法
    • Callable接口:Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。
      • 同Runnable区别
        • Callable规定的方法是call(),Runnable规定的方法是run().
        • Callable的任务执行后可返回值,而Runnable的任务是不能返回值
        • call方法可以抛出异常,run方法不可以
    • Future接口
      通过线程池ExecutorService运行submit方法可以拿到一个Future对象,Future 表示异步计算的结果,它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。Future的cancel方法可以取消任务的执行,它有一布尔参数,参数为 true 表示立即中断任务的执行,参数为 false 表示允许正在运行的任务运行完成。Future的 get 方法等待计算完成,获取计算结果
  • ②线程的状态
    线程具有固定的操作状态
    创建状态:准备好了一个多线程对象
    就绪状态:调用start()方法,等待CPU进行调度
    运行状态:执行run()方法
    阻塞状态:暂时停止执行,可能将资源交给其他线程使用
    终止状态:也称为死亡状态,线程销毁
  • ③线程常用方法
    • getName():取得线程名称
    • currentThread():取得当前线程对象
    • isAlive():判断线程是否启动
    • join():线程的强制运行
    • sleep():线程的休眠
    • yield():线程的礼让,Thread.yield(),即满足某一条件后,线程不在执行,切换其他线程运行
  • ④线程优先级:通过Thread.setPriority 设置优先级
  • ⑤线程同步与死锁

    • 同步前提:多个线程,且使用同一锁对象,能够解决多线程安全问题。弊端在于线程相当多时耗费资源,降低程序运行效率。
    • 原子性操作:即不可中断的操作,比如赋值操作。原子性操作本身是线程安全的。
      • java.util.concurrent.atomic包:JDK6新增,里面有各种原子类,比如AtomicInteger。而AtomicInteger提供了各种自增,自减等方法,这些方法都是原子性的(i++、i–不是原子性操作)。 换句话说,自增方法 incrementAndGet 是线程安全的,同一个时间,只有一个线程可以调用这个方法。
    • 同步代码块:在代码块上加上“synchronized“关键字,则此代码块就称为同步代码块(方法也可以同步),资源共享的时候需要使用同步
      格式:

      1. synchronize(锁对象)
      2. {
      3. 需要同步的代码块;
      4. }
    • 锁对象
      同步代码块的锁对象:任意对象
      同步方法的锁对象:this
      静态方法的锁对象:当前类的.class文件

    • Lock锁:近似于同步代码块,通过Lock.lock()、Lock.unlock()方法加锁、释放锁,通常使用try…final…完成锁

  • ⑥线程的生命周期

  • ⑦线程组

    • 把多个线程组合到一起,可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制
    • 通过ThreadGroup类设置线程组,常用方法:
      • getName():获取线程组名称
      • setDaemon():设置后台线程,true表示改组的线程都是后台线程、守护线程
      • destroy():销毁线程组
  • ⑧线程池

    • 程序启动新线程成本较高,因为涉及与操作系统的交互。使用线程池可以很好的提高性能,尤其当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。
    • Executors类定义的 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类的工厂和实用方法。
    • Java通过Executors工厂类提供四种线程池,返回ExecutorService接口,分别为:
      • newCachedThreadPool
        创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
      • newFixedThreadPool
        创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
      • newScheduledThreadPool
        创建一个定长线程池,支持定时及周期性任务执行。
      • newSingleThreadExecutor
        创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

反射

  • 类的加载:当程序要使用某个类时,如该类尚未加载到内存中,则系统会通过加载、连接、初始化三步来实现对这个类的初始化
    • 加载:就是将class文件读入内存,并为之创建一个Class对象。任何类使用时系统都会建立一个Class对象。
    • 连接
      • 验证:是否有正确的内部结构,并和其他类协调一致。
      • 准备:负责为类的静态成员分配内存,并设置默认初始化值。
      • 解析:将类的二进制数据中的符号引用替换为直接饮用。
    • 初始化:即Java中类的初始化步骤。
      初始化时机:

      • 创建类的实例
      • 调用类的静态方法
      • 使用反射方式强制创建某个类或接口对应的Class对象
      • 初始化某个类的子类
      • 直接使用java.exe命令来运行某个主类
  • 反射:JAVA反射机制是在运行状态中,对于任意一个类都能够知道这个类的所有属性和方法;对于任何一个对象,都能调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能成为JAVA语言的反射机制。所以必须要获取到该类的字节码文件,首先就要获取每一个字节码文件对应的Class类型的对象。
    • 获取Class方式
      • Object类中的getClass方法
      • 数据类型的静态属性class
      • Class类中的静态方法 forName(string ClassName)注:ClassName要写全路径,即package.ClassName
    • Class类方法
      • getConstructors:返回所有公有构造方法,Constructor类的数组形式。
      • getDeclaredConstructors:返回所有构造方法
      • getField/getDeclaredField:返回成员变量,Field类。通过Field类中set方法可以设置变量值。
      • getMethod/getDeclaredMethod:返回方法,Method类。通过Method类中inovke方法调用,invoke第一个参数传对象,后面的参数传方法参数。
    • Constructor类方法
      • newInstance:创建新实例
      • setAccessible(boolean):参数为布尔值,值为true时暴力访问,指示反射的对象在使用时取消Java语言访问检查,即无视访问修饰符存在。
  • 动态代理:在程序运行过程中产生代理对象,通过反射生成(通过java.lang.reflect包下Proxy类和InvocationHandler接口实现)。JDK提供的代理只能针对接口做代理,cglib提供更强大代理。
    • Proxy类:使用newProxyInstance方法生成代理后的对象
    • InvocationHandler接口:使用invoke(Object proxy, Method method, Object[] args)方法生成代理对象

注解

注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

  • 作用分类:
    • 编写文档:通过代码里标识的元数据生成文档【生成文档doc文档】
    • 代码分析:通过代码里标识的元数据对代码进行分析【使用反射】
    • 编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】

基本内置注解

  • @Override
    用在方法上,表示这个方法重写了父类的方法,如toString()。如果父类没有这个方法,那么就无法编译通过

  • @Deprecated
    表示这个方法以及过期,不建议开发者使用。

  • @SuppressWarnings
    这个注解的用处是忽略警告信息。有常见的值,分别对应如下意思:

    1. deprecation:使用了不赞成使用的类或方法时的警告(使用@ Deprecated使得编译器产生的警告);
    2. unchecked:执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型; 关闭编译器警告
    3. fallthrough:当 Switch 程序块直接通往下一种情况而没有 Break 时的警告;
    4. path:在类路径、源文件路径等中有不存在的路径时的警告;
    5. serial:当在可序列化的类上缺少 serialVersionUID 定义时的警告;
    6. finally:任何 finally 子句不能正常完成时的警告;
    7. rawtypes 泛型类型未指明
    8. unused 引用定义了,但是没有被使用
    9. all:关于以上所有情况的警告。
  • @SafeVarargs
    只能用在参数长度可变的方法或构造方法上,且方法必须声明为static或final,否则会出现编译错误。使用前提是开发人员必须确保这个方法的实现中对泛型类型参数的处理不会引发类型安全问题。

  • @Functionallterface
    是Java1.8 新增的注解,用于约定函数式接口。
    函数式接口概念: 如果接口中只有一个抽象方法(可以包含多个默认方法或多个static方法),该接口称为函数式接口。函数式接口其存在的意义,主要是配合Lambda 表达式 来使用。

自定义注解

  • 创建注解
    创建注解类型的时候即不使用class也不使用interface,而是使用@interface
    如:public @interface JDBCConfig

  • 元注解

    • @Target
      说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。

      • 作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
      • 取值:
        1. 1.CONSTRUCTOR:用于描述构造器
        2. 2.FIELD:用于描述域
        3. 3.LOCAL_VARIABLE:用于描述局部变量
        4. 4.METHOD:用于描述方法
        5. 5.PACKAGE:用于描述包
        6. 6.PARAMETER:用于描述参数
        7. 7.TYPE:用于描述类、接口(包括注解类型) enum声明
    • @Retention(RetentionPolicy.RUNTIME)
      定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。

      • 作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
      • 取值:
        1. 1.SOURCE:在源文件中有效(即源文件保留)
        2. 2.CLASS:在class文件中有效(即class保留)
        3. 3.RUNTIME:在运行时有效(即运行时保留)
    • @Inherited
      阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

    • @Documented
      用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。

  • 注解解析
    用自定义注解把目标类改造为注解方式类,通过反射Object.class.getAnnotation(自定义注解.class);获取注解方式类的注解对象
    通过调用注解对象的内部方法获取各个注解元素的值


关键字

  • this关键字

    1. 表示类中的属性和调用方法
    2. 调用本类中的构造方法(必须放在首行
    3. 表示当前对象
  • static关键字

    1. 使用static声明全局属性
    2. 使用static声明方法,直接通过类名调用
    3. 使用static方法,只能访问static声明的成员变量和方法,而非static声明的属性和方法是不能访问的
    4. 静态方法中没有this关键字,因为静态随着类加载而加载,this是随着对象创建而存在的
  • super关键字
    代表父类存储空间的标识,强行调用父类构造方法执行,可用于方法重写,也可以表示哪些方法是由父类中继承而来。

  • final关键字

    • 被称为完结器,表示最终。能声明类、方法、属性。
    • 使用final声明的类不能被继承,声明的方法不能被重写,声明的变量变为常量,不能被修改。
    • 初始化时机:final修饰的变量只能赋值一次,在构造方法完毕前赋值
    • final修饰局部变量时,如果是基本类型,值不能改变;如果是引用类型,地址值不能改变,但对象内容可以改变
  • instanceof关键字
    用于判断某对象是否由某类实例化,返回Boolean值

  • package关键字
    用来定义包。
    注意事项:

    • package语句必须是程序的第一条可执行代码
    • package语句在一个JAVA文件中只能有一个
    • 如果没有package,表示默认无包名
  1. package 包名;//多级包用.分开即可
  • transient关键字
    变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话来说就是,用transient关键字标记的成员变量不参与序列化过程。

  • import关键字
    用来导入包。
    注意事项:

    • 这种方式导入是到类的名称
    • 虽然可以最后写*,但是不建议
    • 顺序:package>import>class,package只能有一个,import可以有多个,class可以有多个但是建议一个
  1. import 包名;

常用语句

  1. syso –>System.out.println(); 控制台输出 System.in输入(实例Scanner类),System.err.println()优先级更高,一般用于调试
  2. switch语句内表达式可以传入 int short char byte、枚举、String;case下如果不加break可能会发生switch穿透,即顺延下个case
  3. ‘\t’ tab键 ‘\r 回车键 ‘\n’ 换行键(不同系统下换行符不同,Windows:\r\n,Linux:\n,Mac:\r)

Eclipse常用快捷键

  1. ctrl+shift+F 重新格式化
  2. alt+shift+S弹出Source快捷菜单
  3. ctrl+1快速修复
  4. alt+shift+M 提炼方法,抽取一段代码生成新的方法
  5. alt+shift+R 重命名方法名、属性或者变量名
  6. /**+ENTER 生成Java Doc,方法前操作可添加参数说明。
  7. ctrl+shift+O/M 组织包/导入包

编程习惯

  • JavaDoc格式
    生成JavaDoc后,@para 表示传入参数,@return表示返回值,@author 表示作者,@version 表示版本号

    • 格式:cmd命令: javadoc -d 目录 -author -version 程序名称.java
    • 使用Eclipse生成JavaDoc出现乱码错误时,在VM Option选项下加入:“-encoding utf-8 -charset utf-8”(以UTF-8为例)
  • Package作用
    把相同的类名放在不同的包下,对类进行分类管理。分类方法:①按照功能分 ②按照模块分
    带包的编译和运行:

    • 手动式
    1. 编写一个带包的Java文件
    2. 通过Javac命令编译该Java文件
    3. 手动创建包名
    4. 把2步骤的class文件放到c步骤的最底层包
    5. 回到和包根目录在同一目录的地方,然后运行(带包运行)
    • 自动式
    1. Javac编译的时候带上 -d . 即可
      如:javac -d . HelloWorld.java
    2. 通过java命令执行,和手动式一样

常见问题

  • 命令行窗口下,Java执行class报出“找不到或无法加载主类”,环境变量配置无误,出错原因可能为:
    • package路径不正确,class文件没有严格按照package路径存放
    • 命令行执行java命令时,class文件不要加.class后缀