Java基础知识回顾
Posted ksea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础知识回顾相关的知识,希望对你有一定的参考价值。
Java-base
数组
数组必须初始化
默认值与类型有关内存分配
对于int[] arr = new int[3];
左边在内存有一个区域(栈内存,局部变量(指向于new出来对象的首地址首地址),使用完毕立即消失),右边也有一个区域(堆内存,new出来的东西(地址+数据),垃圾回收器空闲时清理)
左边arr指向于数组的首地址
方法
重载
同一个类的多个方法具有相同名,但是参数个数或者类型不同,称之方法重载- 内存分配
形参修改
main方法先进栈内存,带有实参
然后调用方法(带形参)进栈内存,在调用的方法中修改形参
分别占有栈内存两个区域,所以形参的改变不影响实参引用类型
通过引用修改堆内存的数据,故改变了实参
Debug
- 意义
在于查看自己所写代码在运行中的流程,变量的如何变化,即程序的跳转方向顺序 - 用法
- 打断点
- 按F7,从断点处执行下一行,遇到输入语句,要在console中先输入数据
对象
- 内存分配类似于数组
- 成员变量与局部变量
- 成员变量:类内的变量,堆内存,随着对象消失而消失,有默认初始值
- 局部变量:成员方法内的变量,栈内存,随着方法调用消失而消失,没有默认初始值必需先赋值
- this关键字
局部变量与成员变量同名,用this指向成员变量,用于区分两者,谁调用this指向那个对象 - 构造方法
- 会默认执行构造方法中的语句
- 构造方法根据参数个数的不同会有多种,建议手写默认无参构造
API
- 使用流程
- 点击索引,输入查找类
- 先看在哪个包
- 查看功能描述
- 查看构造方法
- 重点关注成员方法,关注方法的返回类型,所需参数,功能描述
字符串
- String字符串为常量,值不可变
- 特点:当使用
String str = "abc"
创建字符串,堆内存中会在常量池中存放一个"abc"字符串,当创建一个内容相同内容的字符串String str1 = "abc"
,它也会去常量池中找,故栈内存的str1与str2指向地址相同的 - == 基本类型比较的是数据值,引用类型比较的是地址值;equals比较的是数据值(字符串为对象,即引用类型,比较内容是是通过equals)
- StringBuilder字符串为变量,值可变。自带append()方法和reverse()方法,好处在于不用每声名一个str,都要在堆内存中的常量池中消耗内存空间存放str
- String与StringBulide的转换
- String-->StringBuilder 通过StringBuilder(str)的构造方法
- StringBuilder->String 通过strBuilder.toString()
集合
- Collection(单列)和Map(双列)
- Collection
- add()
- remove()
- clear()
- contains()
- isEmpty()
- size()
- 遍历:Iterator Collection集合专用遍历器,集合类的成员变量
- it.hasNext()
- it.next()
- List(可重复,有序)与Set(不可重复)
- List
- add()
- remove()
- set()
- get()
- ListIterator List专用遍历器,可以双向遍历
- List常用集合ArrayList(顺序表)和LinkedList(链表)
- ArrayList:可调整大小的数组
常见方法- 无参构造
- add(E e) 添加到集合尾端
- add(int index,E element) 指定位置插入元素
- remove(Object o) 删除指定内容的元素
- remove(int index) 删除指定下标的元素
- set(int index,E element) 修改指定下标的元素
- get(int index) 获取指定下标的元素
- size() 获取集合元素个数
- LinkedList
- addFirst()
- addLast()
- getFirst()
- getLast()
- removeFirst()
- removeLast()
- Set 没有索引,不能通过普通for循环遍历,使用add方法时不保证顺序
- 哈希值 根据对象地址或者字符串或者数字计算出来的int类型数值
- hashCode() 获取对象哈希值,通常不同对象哈希值不同,通过重写可以实现不同对象哈希值相同
- HsahSet
- 底层为哈希表
- 顺序不保证一致
- 不能通过普通for遍历
- 不含重复值
- LinkedHashSet 哈希表+链表 不重复但一致
- TreeSet 按一定的规则排序,排序方式取决于构造方法
- Comparable 自然排序器(接口)
- Comparator 比较器排序(类)
- 泛型
- 优点:把运行时期的问题提到编译期;避免了强制转换
- 泛型类与泛型方法:先用泛型给出参数类型,先不明确类型,根据实际调用才决定类型,提高代码复用性
- 泛型接口
- 类型通配符 <?> <? extends a> <? super b>
- Map 键值一一对应,键唯一性
- 创建方式 多态子类
- put() 键值关联
- remove()
- clear()
- containsKey()
- containsValue()
- isEmpty()
- size()
- get() 根据键获取值
- keySet() 获取所有键集合
- values() 获取所有值集合
继承
- 优点:提高代码复用性,维护性
- 缺点:耦合性增强,当父类发生改变,子类也要变
- 使用条件:符合A is B。例如猫属于动物
- 成员方法中调用一个变量的访问顺序:先在方法内部找,其次类的成员变量(this.本类对象引用),最后父类的成员变量(super.父类对象引用)
- 调用子类无参或者有参构造方法,会先调用父类中无参构造方法(默认有一句super(),可以通过改写该方法实现子类创建时父类带参构造)。子类初始化之前一定要先完成父类数据的初始化。
- 方法重写:子类出现和父类一样声名的方法,子类中添加独有方法,并继承了父类的拥有的方法,通过super调用,可以用@Override检查重写方法声明的正确性。
- 父类中私有内容,子类无法继承
- 要注意访问权限,子类重写父类方法权限不能低于父类低
- 单继承和多层继承
final
- 方法 不能被重写
- 类 不能被继承
- 基本变量 不能被修改内容
- 引用变量 不能被修改的是地址,但是地址内容可以修改
static
- 修饰成员方法与成员变量
- 被类的所有对象共享
- 可以通过对象或者类调用被静态的内容,推荐通过类名访问
- 非静态可以访问静态与静态,静态仅可访问静态
多态
- 成员变量:编译看左边,执行看左边
- 成员方法:编译看左边,执行看右边 (成员方法被重写导致)
- 好处:提高程序扩展性,定义方法时用父类型作为参数,将来使用时使用具体的子类型参与操作,即都可以访问父类的方法,对于新类型仅需创建一个新的类,通过继承父类,即可利用多态,即可访问父类方法
- 弊端:不能使用子类特有的功能
- 转型:使之能访问子类的特有功能
- 具体类多态,抽象类多态,接口多态
抽象类
- 有抽象方法必须为抽象类(即没有方法体)
- 抽象类可以有非抽象方法
- 抽象类的创建对象通过,抽象类多态即子类对象实例化,继承了抽象类的子类必需重写父类中所有的抽象方法或者其本身为一个抽象类
- 抽象类不可直接实例化也需要构造方法,构造方法用创建子类时数据初始化
接口
- 内容为常量和抽象方法
- 接口中的成员变量默认被static和final修饰
- 无构造方法
- 单继承多实现
- 接口可以多继承接口
- 设计应用:抽象类是对事物的抽象,接口是对行为的抽象,例如:门有开,关,附加一个报警功能,可通过继承带有开,关功能的抽象类,实现带有报警功能的抽象类。可以理解为抽象类提供共有,接口提供特有
- 作为形参,返回的是它的实现类
内部类
- 成员内部类(成员变量)
使用方法,通过外部类创建一个方法一,在该方法一中创建内部类,实例化外部类,调用方法一 - 局部内部类 (成员方法内)
使用方法,间接调用,通过在外部类的一个方法中创建内部类 - 匿名内部类:没有名字的实例化了 类或者接口 的子类匿名对象
常用API
- 看方法源码,选择方法,Crtl+B
- Math
- System
不能实例化,但是所有方法都被静态修饰,可以直接通过类名调用- exit() 终止虚拟机
- currentTimeMillis() 返回当前时间,可用于计算程序运行时间
- Obeject:不直接继承父类的类都为其子类
- equals()
- toString() :建议所有子类都重写这个方法,例如syso对象时,先重写toString
- Date
- setTime() 设置当前时间
- getTime() 与1907的毫秒差
- SimpleDateFormat() 按自己需要格式化时间格式
- 字符串与Date对象的相互转化,通过SimpleDateFromat.format()与parse()俩个方法
- Calendar
- getInstance() 初始化
- 根据Api给出的相关字段去获取具体年月日
- add() 修改时间,增加或者减去一段时间
- set() 修改时间,直接设置(月份从0起)
基本类型与包装类
- int与Integer
- int与String
- 自动装箱和拆箱
- 装箱:int转Integer,valueOf();
- 拆箱:Integer转int,intValue();
异常
- Error 表示严重问题,不处理
- Eception 异常类 程序本身可处理问题
- RuntimeException 编译时期不检查,出现问题后需回来修改代码
- 非RuntiemEception 编译时期需要检查
- JVM默认处理异常方案:输出异常信息,结束程序
- Throwable的三个常见成员方法
- getMessage()
- toString()
- parintStackTrace()
- 编译时期的异常
- try...catch
- throws
File
- 文件和目录封装成的对象,仅仅是路径名,文件不一定存在,相当于封装了个字符串
- 创建功能 通过File实例化的对象调用
- createNewFile() 文件
- mkdir() 文件夹
- mkdirs() 多级文件夹
- 删除
- delete()
- 递归遍历目录
IO
- 字节流和字符流
- 文字用字符流
- 其他情况用字节流,万能流
- 字节输入流:(抽象类)InputStream[int read(),int read(byte[] bytes)]---FileInputStream---BufferdInputStream
- 字节输出流:(抽象类)OutputSream[void write(int by),void write(byte[] bys,int index,int len)]---(常用具体子类)FileOutputStream---BufferedInputStream
- 字符输入流:(抽象类)Reader---InputStreamReader---BufferedReader------FileReader
- 字符输出流:(抽象类)Writer---OutputStreamWriter---BufferedWriter------FilerWriter
- 输入流与输出流
- InputStream 字节输入流超类 读取文件
1.1 读的方式有一次读一个字节,一次读一个字节数组
2.2 read()方法当遇到null返回值为-1,返回的是字节总个数
2.3 readLine() - OutputStream write 字节输出流超类 写入文件
2.1 输出流换行符 转义" "
,
2.2 追加写入 创建流的时候添加参数append:true
2.3 写的方式有一次写一个字节,一次写一个字节数组,一次写一个数组的偏移量
2.4 newLine()
- InputStream 字节输入流超类 读取文件
- 缓冲流 提高输入输出的效率 BufferOutputStream(FileOutputStream) BufferInputStream(FileInputStream)
- 复制实现
- 根据数据源创建字节输入流对象
- 根据数据存放地创建字节输出流对象
- 读写数据,写入数据(一次处理一个数组或者一个字节)
- 释放资源
- 字符流的意义
- 字节流对中文操作不方便
- 识别中文,中文第一个字节为负数
- GBK = 2个字节,Utf-8 = 3个字节
- 字符流 = 字节流+编码表
- 默认编码为 utf-8
- 编码与解码 以A编码 需要以A解码
- getBytes() 把String编码为一系列字节。可以通过参数来决定编码方式
- String(byte[] bytes) 把字节数组解码为一个String
- Reader与Writer 字符流
字符字节流的相互转化通过InputStreamReader,OutputStreamWriter - 对象序列化和但序列化
- ObjectOutputStream 序列化的类需要实现接口Serializable
- ObjectInputStream
线程
- 创建方法
- 继承Thread类,重写run()[run是用来封装呗线程执行的代码]
- 实现Runnable接口 避免单继承的局限性,线程和程序代码分离
- 常用方法
- 获取线程名称 setName()
- 设置县城名称 getName()
- 获取当前正在运行的线程 Thread.currentThread().getName()
- 返回线程优先级 getPriority()
- 设置线程优先级 setPriority() 只是几率高,不是一定 范围1~10 默认5
- 暂停线程 sleep(long millis)
- 等待线程死亡 join() 当前线程执行完毕 其他线程再执行
- 守护线程 setDaemon(Boolean on) 主线程执行完毕,被设置为守护的线程随之结束
- wait() 等待
- nitify() 唤醒
- 同步
- 多线程环境
- 共享数据
- 多条语句对共享数据的操作
满足三个条件,会出现数据安全的问题,通过同步代码块来解决synchronized(Object obj) 或者 同步方法用synchoronized修饰方法,非同步锁为this,静态的同步锁.class
- 常见线程安全类
- StringBuilder
- Veotor相同功能ArrayList
- Hashtable相同功能HashMap
- 锁
常见方法- lock() 加锁 放在try块中
- unlock() 释放锁 放在finally块中,确保释放资源
- new ReentrantLock() Lock为接口,通过实现类来实例化
- 生产者与消费者
网络编程
- 三要素:Ip地址,端口,协议
- InetAddress Ip地址类
- getByName(String str) 确定主机名称的Ip地址
- getHostName() 获取主机名称
- getHostAddress() 获取Ip地址
- 协议
UDP:无连接通信协议,效率高,安全性低,如音频,视频
TCP:面向连接的通信协议,传输数据之前需要先建立逻辑连接,即三次握手
三次握手:1. 客户端发送连接请求 2. 服务器发送响应,告知收到了连接请求 3.客户端发送确认信息,确认连接 UDP 没有客户端和服务器概念,只管发送不管有没有收到
UDP发送数据步骤- 创建发送端的Socket对象
- 创建数据并且打包
- 调用Socket的方法发送数据
- 关闭发送端
- 创建接收端Socket,带参构造,指定端口
- 创建一个数据包接收数据
- 调用Socket的方法接收数据
- 解释数据
- 关闭接收端
- TCP
客户端Socket- 创建Socket
- 获取输出流,写数据
- 释放资源
- 创建ServerSocket
- 获取输入流,读数据,并把数据显示在控制台 accept()
- 释放资源
- TCP实现文件上传的思路
TCP结合IO流的应用
反射
- 类加载 把class文件加载到内存,创建一个对象
- 创建类的实例
- 调用类方法
- 访问类变量
- 反射
- 访问其子类
- 类加载器
- 反射概述 在运行时去获取一个类的变量和方法信息,通过这些信息来创建对象,简化了创建类步骤提升了灵活性,通过Class来调用类的方法变量
获取Class类,反射的方法都是通过Class去调用- className.class
- Object.getClass()
- Class.forName(String className)
- 反射获取类的构造方法 Constructor
- getConstructors() 返回所有公共构造方法对象的数组
- getDeclaredConstructors() 返回所有构造方法对象
- getConstructor(Class<?>...parameterTypes) 返回单个公共构造方法对象
- getDeclaredConstructior(Class<?>...parameterTypes) 返回单个构造方法对象 传入相关参数
- 创建对象等相关的方法在Constructor类中 Constructor.newInstance(Object)
- 反射获取成员变量
- Field[] getFields() 获取公共变量
- Field[] getDeclaredFields() 获取所有变量
- Field[] getField(String name)
- Field[] getDeclaredField(String name)
- 变量赋值等相关操作方法在Field类中
- 暴力使用,取消访问检查,即可以调用私有变量,通过Field.setAccessible(true)
- 反射获取成员方法
- Method[] getMethods()
- Method[] getDeclaredMethods()
- Method.invoke() 调用方法
- 反射应用之在整型集合中添加字符串,原理:通过反射可以获得参数原始类型
以上是关于Java基础知识回顾的主要内容,如果未能解决你的问题,请参考以下文章