java基础笔记
第一章 入门须知
1.1 程序开发步骤
- 编写
- 编译:将我们编写的java源文件翻译成jvm认识的class文件,此过程编译器会检查我们所写的程序是否有语法错误
- 运行
1.2 标识符
- 定义:自己定义的内容,如类名,方法名,变量名
- 命名规则:
- 可以包含:**字母,数字,$(美元符号),_(下划线)**
- 不能以数字开头
1.3 数据类型转换
- 自动转换:自动向更适应的类型转换(自动将类型提升)
- 强制转换:随你,但要看能不能转换成功
- 加减运算默认是在int类型下的,所以short类型也会发生自动转换
- short s = 1; s = s + 1;//编译失败
public static void main(String[] args){
byte b1=1;
byte b2=2;
//对于常数,编译器是知道的,所以会自动得出结果3,从而确定没有越界而顺利赋值
byte b3=1 + 2;
//对于变量,编译器不知道值是多少,会进行自动转换,从而报错,出现异常
byte b4=b1 + b2;
System.out.println(b3);
System.out.println(b4);
}
1.4 运算符
- && 短路与:左边是false,右边就不再运算
- || 短路或:左边是true,右边就不再运算
- ! 取反
1.5 方法
- 方法必须定义在一个类中的方法外
- 方法不能定义在方法里
1.6 选择语句
- switch语句中表达式的数据类型可以为
- byte,short,int,char,enum(枚举),JDK7后可以接收字符串
1.7 方法重载
- 同一个类中,方法名相同,参数不同即可(与修饰符和返回值无关)
- 参数不同:个数不同/数据类型不同/顺序不同
- 重载方法调用:jvm通过方法的参数列表,调用不同的方法
1.8 数组
- 定义
int[] arr=new int[4];
int[] arr=new int[]{1,2,3,4};
int[] arr={1,2,3,4};
1.9 java虚拟机的内存分配
- 寄存器:给CPU使用
- 本地方法栈:jvm在使用操作系统功能的时候使用,与我们开发无关
- 方法区:存储可以运行的class文件
- 堆内存:存储对象或者数组,new出来的都存储在堆内存
- 方法栈:方法运行时使用的内存
第二章 面向对象
2.1 定义类
- 成员变量
- 成员方法(把static去掉)
2.2 static关键字
- 作用
- 修饰类变量
- 修饰类方法(静态方法)
- 特点
- 随着类加载而加载,且只加载一次
- 存储于固定的内存区域(方法区中的静态区)
2.3 静态代码块
- 特点
- 在类方法之外
- 随着类的加载而执行一次先于main方法和构造方法的执行
- 作用
- 给类变量进行初始化赋值
2.4 继承
- 特点
- 子类可以直接访问父类中的 非私有 的属性和行为(相当于也是子类的成员变量)
- 若成员变量重名,默认方法的是子类成员变量,若想访问父类的,使用关键字 super
- 成员方法重名-重写
- 要求 返回值类型,方法名,参数列表都相同
- 继承后的特点-构造方法
- 继承执行的过程
- 加载父类的静态变量(是那种一上来就赋了初始值)
- 加载父类的静态代码块
- 加载子类的静态变量
- 加载子类的静态代码块
- 加载父类的成员变量
- 加载父类的构造函数
- 加载子类的成员变量
- 加载子类的构造函数
2.5 抽象类
- 特点
- 抽象类不能实例化
- 抽象类可以由构造方法,供子类创建对象时,初始化父类成员使用
- 抽象类可以不包含抽象方法,
- 抽象类中可以由方法,属性(私不私有都行)
2.6 接口
特点:封装了方法
- 抽象方法
默认方法(JDK8)(public default void fly(){}):可以被继承,可以被重写
- 静态方法(JDK8):只能由接口调用
- 私有方法(JDK9)::只能由默认方法调用
- 私有静态方法(JDK9):只能由默认方法和静态方法调用
- public static final 声明的变量(相当于常量,必须赋值)
- 接口中没有构造方法
- 接口中没有 静态代码块
接口中没有成员变量
2.7 多态
- 向上转型(这是个默认过程)
- 向下转型(需要用户标记强制转换)
- instanceof关键字
变量名 instanceof 数据类型
如果变量属于该数据类型,返回true。
如果变量不属于该数据类型,返回false。
Animal a=new Cat;
if(a instanceof Cat){}
2.8 final关键字
- 修饰类:不能被继承
- 修饰方法:不能被重写
- 修饰变量:不能重写赋值
2.9 权限修饰符
- public:权限最高
- protected:同一个包内,不同包的子类可以访问
- default:同一个包内可以访问(不同包的子类不可以访问)
- private:同一类可以访问
2.10 内部类
访问特点
- 内部类可以直接访问外部类的成员,包括私有成员
- 外部类要访问内部类必须要建立内部类对象
外部类名.内部类名 对象名 = new 外部类型().new 内部类型();
内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名 和$符号 。
比如,Person$Heart.class
2.11 匿名内部类
- 定义:本质是一个带具体实现的父类或父接口的匿名子类对象
- 格式
new 父类名或者接口名(){
// 方法重写
@Override
public void method() {
// 执行语句
}
};
- 使用方法
FlyAble f = new FlyAble(){
public void fly() {
System.out.println("我飞了~~~");
}
};
//调用 fly方法,执行重写后的方法
f.fly();
2.12 装箱与拆箱
- Java 5后这个过程是自动完成
2.13 泛型(重点)
- 特点:编译时期的语法约束规则,(不满足泛型所规定的约束,编译就都不能通过,高级开发工具会有红色提示)
- 定义格式
- 在创建对象的时候确定泛型
修饰符 class 类名<代表泛型的变量> { }
class ArrayList{
public boolean add(E e){ }
public E get(int index){ }
....
}
ArrayList list = new ArrayList();
//此时
class ArrayList{
public boolean add(String e){ }
public String get(int index){ }
...
}
- 含有泛型的方法
- 调用方法时,确定泛型的关联
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
public class MyGenericMethod {
public void show(MVP mvp) {
System.out.println(mvp.getClass());
}
}
public class GenericMethodDemo {
public static void main(String[] args) {
// 创建对象
MyGenericMethod mm = new MyGenericMethod();
// 演示看方法提示
mm.show("aaa");
mm.show(123);
mm.show(12.45);
}
}
- 含有泛型的接口
- 定义类时确定泛型的类型
- 始终无法确定泛型的类型,则在创建对象时确定泛型类型
修饰符 interface接口名<代表泛型的变量> { }
public interface MyGenericInterface{
public abstract void add(E e);
public abstract E getE();
}
public class MyImp1 implements MyGenericInterface {
@Override
public void add(String e) {
// 省略...
}
@Override
public String getE() {
return null;
}
}
//还是无法确定泛型
public class MyImp2 implements MyGenericInterface {
@Override
public void add(E e) {
// 省略...
}
@Override
public E getE() {
return null;
}
}
/*
* 使用时确定泛型
*/
public class GenericInterface {
public static void main(String[] args) {
MyImp2 my = new MyImp2();
my.add("aa");
}
}
泛型通配符
泛型的上限:
- 格式:
类型名称 extends 类 > 对象名称
- 意义:
只能接收该类型及其子类
泛型的下限:
- 格式:
类型名称 super 类 > 对象名称
- 意义:
只能接收该类型及其父类型
2.14 增强for
- 格式
for(元素的数据类型 变量 : Collection集合or数组){
//写操作代码
}
//使用增强for遍历
for(String s :coll){//接收变量s代表 代表被遍历到的集合元素
System.out.println(s);
}
3.15 可变参数
- 格式
修饰符 返回值类型 方法名(参数类型... 形参名){ }
等价于
修饰符 返回值类型 方法名(参数类型[] 形参名){ }
第三章 API
3.1 String类
- 特点
- 字符串的值被创建后不能修改
- 因为不能修改,所以String对象可以共享
- 方法
public boolean equals (Object anObject)
public boolean equalsIgnoreCase (String anotherString)
public char[] toCharArray ()
public byte[] getBytes ()
public String replace (CharSequence target, CharSequence replacement)
public String[] split(String regex) //按照给定的正则规则分割成字符串数组
3.2 Arrays类(工具类)
- 方法
public static String toString(int[] a)
public static void sort(int[] a) //默认升序排序
3.3 Math类(工具类)
- 方法
public static double abs(double a) //求绝对值
public static double ceil(double a)
public static double floor(double a)
public static long round(double a)
3.1 ArrayList
- 父类
- List
- 实例化
List list = new ArrayList<>();
- 成员方法
public boolean add(E e)
public E remove(int index)
public E get(int index)
public int size()
3.4 Object类
- 所有类默认继承该类
- 方法
public String toString() //经常被重写
public boolean equals(Object obj) //默认是地址比较,而我们经常把他改成值比较,然后再配合hasCode()方法完成判断对象是否相同
3.5 Objects类(工具类)
- 静态方法
//判断两个对象是否相等
public static boolean equals(Object a, Object b){
return (a == b) || (a != null && a.equals(b));
}
3.6 Date类
构造函数和方法
public Date()
public Date(long date)
public long getTime()
System.out.println(new Date()); // Tue Jan 16 14:37:35 CST 2018
3.7 DateFormat类(抽象类)
- 作用:将Date对象和String对象之间来回转化
- 格式化(将Date对象转化为指定格式的String对象)
- 解系:按照指定格式,从String对象转换为Date对象
- 实现类:SimpleDateFormat
- 实现类构造方法和方法
- 标识字母:
- y:年
- M:月
- d:日
- H:时
- m:分
- s:秒
public SimpleDateFormat(String pattern) //构造方法,参数为日期格式
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public String format(Date date)
public Date parse(String source)
DateFormat df = new SimpleDateFormat("yyyy年MM月dd日");
String str = "2018年12月11日";
Date date = df.parse(str);
3.8 Calendar类(抽象类)
静态方法
public static Calendar getInstance()
Calendar cal = Calendar.getInstance();
常用方法
public int get(int field)
public void set(int field, int value)
public abstract void add(int field, int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量。
public Date getTime()
field选项
YEAR:年
MONTH:月(从0开始,可以+1使用)
DAY_OF_MONTH:月中的天(几号)
HOUR:时(12小时制)
HOUR_OF_DAY:时(24小时制)
MINUTE:分
SECOND:秒
DAY_OF_WEEK:周中的天(周几,周日为1,可以-1使用)
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2020);
cal.add(Calendar.DAY_OF_MONTH, 2); // 加2天
cal.add(Calendar.YEAR, -3); // 减3年
3.9 System类
- 静态方法
public static long currentTimeMillis()
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length):
public static void main(String[] args) {
int[] src = new int[]{1,2,3,4,5};
int[] dest = new int[]{6,7,8,9,10};
System.arraycopy( src, 0, dest, 0, 3);
/*代码运行后:两个数组中的元素发生了变化
src数组元素[1,2,3,4,5]
dest数组元素[1,2,3,9,10]
*/
}
3.10 StringBuilder类
- 特点
- 默认16个字符空间,超过自动扩展
- 非线程安全,但速度快
- 构造方法和常用方法
public StringBuilder()//空容器
public StringBuilder(String str) //指定初值的容器
public StringBuilder append(任意类型)//都看成表面上的字符串
public String toString()
3.11 包装类的parseXxx静态方法
int num = Integer.parseInt("100");
short num = Short.parseShort("10");
Byte b = Byte.parseByte("a");
Long num = Long.parseLong("10");
Float num = Float.parseFloat("10.7");
Double num = Double.parseDouble("10.3");
Boolean num = Boolean.parseBoolean("10");
第四章 集合
4.1 集合分类
- Collection(接口)
- List(接口):有序,允许重复元素
- ArrayList:基于数组结构,最常用,查询方便
- LinkedList:基于链表结构(双向链表),增删方便
- Vector
- Set(接口):无序,不允许重复元素
- HashSet:基于哈希表实现(哈希表基于数组,链表,红黑树实现),自定义元素需要重写对象中的hashCode和equals方法,确保集合中对象唯一(被排序的类型需要实现Comparable接口)
- LinkedHashSet:实现了存放元素顺序的要求,但还是要求元素不能重复
- TreeSet
- List(接口):有序,允许重复元素
- Map(接口):每次存储一对儿元素(这一对元素为一个整体即 键——值),键值唯一
- TreeMap
- HashMap:存储的自定义键的类型需要重写hashCode方法和equals方法
- TableMap:链表加哈希表,保证了存储先后顺序,保证了键的唯一,
4.2 Connection接口
- 方法
public boolean add(E e)
public void clear()
public boolean remove(E e)
public boolean contains(E e)
public boolean isEmpty()
public int size()
public Object[] toArray()
public Iterator iterator() //返回的是迭代器接口的实现类
4.3 Iterator迭代器(接口)
- 方法
- public E next():返回迭代的下一个元素。
- public boolean hasNext():如果仍有元素可以迭代,则返回 true。
4.4 List接口
- 方法
public void add(int index, E element)
public E get(int index)
public E remove(int index)
public E set(int index, E element)
4.5 LinkedList类(可以作为堆栈)
- 方法
public void addFirst(E e) :将指定元素插入此列表的开头。
public void addLast(E e) :将指定元素添加到此列表的结尾。
public E getFirst() :返回此列表的第一个元素。
public E getLast() :返回此列表的后一个元素。
public E removeFirst() :移除并返回此列表的第一个元素。
public E removeLast() :移除并返回此列表的后一个元素。
public E pop() :从此列表所表示的堆栈处弹出一个元素。
public void push(E e) :将元素推入此列表所表示的堆栈。
public boolean isEmpty() :如果列表不包含元素,则返回true
4.6 Collections(工具类)
- 静态方法
public static boolean addAll(Collection c, T... elements) :往集合中添加一些元素。 public static void shuffle(List> list) 打乱顺序 :打乱集合顺序。 public static void sort(List list) :将集合中元素按照默认规则排序。 public static void sort(List list,Comparator super T> ) :将集合中元素按照指定规则排 序。
4.7 Comparator比较器(接口)
- 抽象方法
public int compare(T o1, T o2)
Collections.sort(list, new Comparator() {
@Override
public int compare(String o1, String o2) {
return o2.charAt(0) ‐ o1.charAt(0);
}
});
两个对象比较的结果有三种:大于,等于,小于。
如果要按照升序排序, 则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数)(即o1大于o2为真)
如果要按照 降序排序 则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)(即o2大于o1为真)
4.8 Map接口
- 方法
public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。 public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的 值。 public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
public Set keySet() : 获取Map集合中所有的键,存储到Set集合中。 public Set> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。
- Entry键值对对象
- 方法
public K getKey() :获取Entry对象中的键。
public V getValue() :获取Entry对象中的值
Set> entrySet = map.entrySet();
// 遍历得到每一个entry对象
for (Entry entry : entrySet) {
// 解析
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"的CP是:"+value);
}
4.9 JDK9关于集合的新特性
- 为List,Set,Map增加了静态工厂方法,可以创建集合的不可变实例
Set str1=Set.of("a","b","c");
//str1.add("c");这里编译的时候不会错,但是执行的时候会报错,因为是不可变的集合
System.out.println(str1);
Map str2=Map.of("a",1,"b",2);
System.out.println(str2);
List str3=List.of("a","b");
System.out.println(str3);
//生成的集合是不可修改的
1:of()方法只是Map,List,Set这三个接口的静态方法,其父类接口和子类实现并没有这类方法,比如 HashSet,ArrayList等待;
2:返回的集合是不可变的;
4.10 Properties类
- 特点
- 继承于Hashtable,属于Map的子类
- 构造方法与方法
public Properties() :创建一个空的属性列表。
public Object setProperty(String key, String value) : 保存一对属性。 public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。 public Set stringPropertyNames() :所有键的名称的集合。
public void load(InputStream inStream) : 从字节输入流中读取键值对。
第五章 异常
5.1 异常体系
- Throwable:异常的根类
- Error:无法通过处理的错误,如内存溢出,如系统崩溃
- Exception:可以处理的异常,(这是我们常说的异常)
- 编译时期异常:编译时期就会检查,如果不处理则编译失败(checked异常)
- 运行时期异常:编译器不会报错,但运行时会出错(runtime异常),我们自己根据情况选择是否要去处理(如IO异常我们需要处理,去释放资源,不然会导致系统奔溃)
5.2 Throwable类
- 方法
public void printStackTrace() :打印异常的详细信息
public String getMessage() :获取发生异常的原因
public String toString() :获取异常的类型和异常描述信息(不用)。
5.3 异常的处理
- 抛出异常throw
- 声明异常throws
- 捕获异常try...catch
- finally代码块
5.5 异常主义事项
- 多个异常如何使用捕获
- 多个异常分别处理
- 多个异常一次捕获,多次处理
- 多个异常一次捕获,一次处理
- 运行时异常被抛出可以不处理。即不捕获也不声明抛出。 (如除以0)
- 如果finally有return语句,永远返回finally中的结果,避免该情况。
- 子类不能抛出比父类抛出范围更大的异常
- 父类方法没有抛出异常,则子类也不能抛出异常,如果有异常,则只能捕获
第六章 多线程与Lambda表达式
6.1 多线程编程
- 概念
- 高内聚低耦合的情况下线程操作资源类
- 不同的线程操作着同一个资源类对象
6.2 创建线程类
- 通过继承Thread类创建多线程(但真正企业中不会这么用)
- 重写Thread的run方法
- 创建Thread的子类实例,即线程对象
- 调用start()方法启动线程
public class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
@Override
public void run() {...}
}
public class Demo01 {
public static void main(String[] args) {
MyThread mt = new MyThread("新的线程!");
mt.start();
}
}
- 实现Runnable接口创建多线程(重点,企业中做法)
- 定义Runnable接口的实现类(进阶:通过匿名内部类创建多线程)
- 作为参数传入Thread对象中
- Thread的对象调用start方法
- 即通过实现Runnable接口创建多线程的好处
- 匿名内部类可以访问外部类中的成员,所以为多个线程共享资源打下来很好的基础。不是匿名内部类则可以通过set方法或构造方法将资源变量(是引用型变量)传入。
- 增加健壮性,实现了解耦
- 线程池中只能存放实现Runnable或Callable类线程,不能直接放继承Thread的类
public static void main(String[] args) {
//共享资源
final Ticket ticket = new Ticket();
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 1000; i++) {
//内部类可直接访问
ticket.sale();
}
}
}, "thread01").start();
}
6.3 Thread类
- 构造方法
public Thread() :分配一个新的线程对象。
public Thread(String name) :分配一个指定名字的新的线程对象。
public Thread(Runnable target) :分配一个带有指定目标新的线程对象。
//重点掌握,这种最常用
public Thread(Runnable target,String name) :分配一个带有指定目标新的线程对象并指定名字
- 常用方法
public String getName() :获取当前线程名称。
public void start() :导致此线程开始执行; Java虚拟机调用此线程的run方法。
public void run() :此线程要执行的任务在此处定义代码。 留给子类重写
public static void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。
public static Thread currentThread() :返回对当前正在执行的线程对象的引用
6.4 线程同步(同步都是加再资源类上的,然后资源类还需要实现runnable接口)
- 同步代码块
- 同步方法
- 锁机制(重点,这个企业用)
//同步代码块
synchronized(同步锁){
需要同步操作的代码
}
//同步方法
public synchronized void method(){
可能会产生线程安全问题的代码
}//对于静态方法,同步锁是该类的字节码对象(类名.class),对于非静态方法,就是this
public class Ticket implements Runnable{
private int ticket = 100;
Lock lock = new ReentrantLock();
@Override
public void run() {
while(true){
lock.lock();
要上锁部分的代码
lock.unlock();
}
}
}
6.5 线程的状态(Thread.State枚举类)
- new:新建的状态
- runnable:获得锁的状态且运行
- blocked:没获得锁时的状态(无法运行)
- waiting(无限等待):会释放掉锁(通过调用锁的wait方法进入无限等待,调用锁的notify方法可以解除无限等待)
- timed waiting(计时等待)
- teminated(终止)
6.7 锁对象的方法(继承于object)
- wait()
- wait(long time)
- notify()
- notifyAll()
6.8 线程池
线程池的顶级接口
EXecutor:但严格意义上说它是产生线程池的工具类的接口
Executors:线程池的工具类
静态方法:
public static ExecutorService newFixedThreadPool(int nThreads) //获取线程池对象
ExecutorService:线程池接口,通过Executors的静态方法获取实现该接口的实例对象
方法
public Future> submit(Runnable task) :获取线程池中的某一个线程对象,并执行 Future接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用 public void shutdown(); 关闭线程池
public class ThreadPoolDemo {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(2);//包含2个线程对象
MyRunnable r = new MyRunnable();
service.submit(r);
// 再获取个线程对象,调用MyRunnable中的run()
service.submit(r);
service.submit(r);
service.shutdown(); //关闭线程池
}
}
6.9 Lambda使用前提
- 使用Lambda表达式前提是要有函数式接口
- 什么是函数式接口
- 接口中只允许有且仅有一个抽象方法。
- 我们将这个函数式接口的匿名内部类的实现方式通过Lambda表达式来构造出来(而不是new)
- 使用Lambda必须具有上下文推断。
- 即方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例
- Lambda表达式操作后来其实是生成了一个匿名内部类
- Lambda表达式的标准格式:
(参数类型 参数名称) ‐> { 代码语句 } //虽然能简写,但是这个是规范,最好使用这样
6.10 Lambda省略规则(不建议)
- 小括号内参数的类型可以省略
- 如果小括号内有且仅有一个参,则小括号可以省略;
- 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号
public static void main(String[] args) {
invokeCook(() ‐> System.out.println("吃饭啦!")); //省略了大括号
}
第七章 文件与流
7.1 File类
- 构造方法
public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。 public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。 public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例
常用方法
public String getAbsolutePath() :返回此File的绝对路径名字符串。 public String getPath() :将此File转换为路径名字符串。 public String getName() :返回由此File表示的文件或目录的名称。 public long length() :返回由此File表示的文件的长度
判断功能方法
public boolean exists() :此File表示的文件或目录是否实际存在。 public boolean isDirectory() :此File表示的是否为目录。 public boolean isFile() :此File表示的是否为文件。
创建删除功能的方法
public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。 public boolean delete() :删除由此File表示的文件或目录。 public boolean mkdir() :创建由此File表示的目录。 public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录
目录遍历方法
public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。 public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。 public File[] listFiles(FileFilter) :返回一个File数组,表示该File目录中的满足过滤器的文件
FileFilter接口
抽象方法:
boolean accept(File pathname) :测试pathname是否应该包含在当前File目录中,符合则返回true
代码实现
public class DiGuiDemo4 { public static void main(String[] args) { File dir = new File("D:\\aaa"); printDir2(dir); } public static void printDir2(File dir) { //匿名内部类实现 File[] files = dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.getName().endsWith(".java")||pathname.isDirectory(); } }); // 循环打印 for (File file : files) { if (file.isFile()) { System.out.println("文件名:" + file.getAbsolutePath()); } else { printDir2(file); } } } }
7.2 (顶级)IO流
- 字节流
- InputStream
- FileInputStream
- BufferedInputStream
- OutputStream
- FileOutputStream
- BufferedOutputStream
- InputStream
- 字符流
- Reader
- FileReader
- BufferedReader
- Writer
- FileWriter
- BufferedWriter
- Reader
7.3 OutputStream抽象类
- 方法
public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。 public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输 出到此输出流。
public abstract void write(int b) :将指定的字节输出流。
7.4 FileOutputStream类
- 构造方法
//这两种默认不支持追加,没有指定文件会自动创建
public FileOutputStream(File file) :创建文件输出流以写入由指定的 File对象表示的文件。 public FileOutputStream(String name) : 创建文件输出流以指定的名称写入文件。
public FileOutputStream(File file, boolean append) : 创建文件输出流以写入由指定的 File对象表示的文件。参数2表示能否追加数据(不能则每次都是先清空在写入数据)
public FileOutputStream(String name, boolean append) : 创建文件输出流以指定的名称写入文件。
7.5 InputStream抽象类
- 方法
public void close() :关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read() : 从输入流读取数据的下一个字节。
public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。
7.6 FileInputStream类
- 构造方法
FileInputStream(File file) ://路径下没有文件会抛异常
FileInputStream(String name) : //路径下没有文件会抛异常
7.7 Reader抽象类
- 方法
public void close() :关闭此流并释放与此流相关联的任何系统资源。
public int read() : 从输入流读取一个字符。
public int read(char[] cbuf) : 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中
7.8 FileReader类
- 构造方法
FileReader(File file) : 创建一个新的 FileReader ,给定要读取的File对象。 FileReader(String fileName) : 创建一个新的 FileReader ,给定要读取的文件的名称。
7.9 Writer抽象类
- 方法
void write(int c) 写入单个字符。
void write(char[] cbuf) 写入字符数组。
abstract void write(char[] cbuf, int off, int len)
void write(String str) 写入字符串。
void write(String str, int off, int len)
void flush() 刷新该流的缓冲。
void close() 关闭此流,但要先刷新它。
7.10 FileWriter类
- 构造方法
FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。 FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。
7.11 字节缓冲流
- 构造方法
public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。 public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流
// 创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));
// 创建字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
7.12 字符缓冲流
- 构造方法
public BufferedReader(Reader in) :创建一个 新的缓冲输入流。
public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。
// 创建字符缓冲输入流
BufferedReader br = new BufferedReader(new FileReader("br.txt"));
// 创建字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
- 特有方法
BufferedReader: public String readLine() : 读一行文字。
BufferedWriter: public void newLine() : 写一行行分隔符,由系统属性定义符号。
7.13 转换流
InputStreamReader类:是Reader的子类
构造方法
InputStreamReader(InputStream in) : 创建一个使用平台默认字符集的字符流。 InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。即按指定编码读取流中的内容。
OutputStreamWriter类:是Writer的子类
构造方法
OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。 OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流。,即按指定的字符类型输出
7.14 序列化
ObjectOutputStream类:将java对象的原始数据类型写到文件中,实现对象的持久存储
构造方法
public ObjectOutputStream(OutputStream out) : 创建一个指定OutputStream的ObjectOutputStream
具体操作
- 被序列化的对象其所属类需要实现Serializable接口,该接口是个标记接口
- 若某个属性不想被序列化,可以使用transient关键字修饰
方法
public final void writeObject (Object obj) : 将指定的对象写出
ObjectInputStream类:反序列化操作
构造方法
public ObjectInputStream(InputStream in) : 创建一个指定InputStream的ObjectInputStream
方法
public final Object readObject () : 读取一个对象。
注意
- 反序列化对象,必须能够找到其class文件的类,若找不到,会抛异常
- 若其class文件的类在序列化对象后发生修改,也会抛出异常
- Serializable接口给需要序列化的类提供了一个序列版本号 serialVersionUID,用于验证序列化的对象与对应类的版本是否匹配
7.15 打印流
PrintStream类
构造方法
public PrintStream(String fileName) : 使用指定的文件名创建一个新的打印流 System.out就是一个PrintStream类型,只不过它是向控制台打印。
public static void main(String[] args) throws IOException { // 调用系统的打印流,控制台直接输出97 System.out.println(97); // 创建打印流,指定文件的名称 PrintStream ps = new PrintStream("ps.txt"); // 设置系统的打印流流向,输出到ps.txt System.setOut(ps); // 调用系统的打印流,ps.txt中输出97 System.out.println(97); }
第八章 网络编程
Socket类:用于客户端套接字
构造方法和成员方法
public Socket(String host, int port)//连上指定主机的端口上 public InputStream getInputStream() : 返回此套接字的输入流 public OutputStream getOutputStream() : 返回此套接字的输出流。 public void close() :关闭此套接字。 //这个也会将流给关闭 public void shutdownOutput() : 禁用此套接字的输出流
ServerSocket类:用于服务端套接字
构造方法和成员方法
public ServerSocket(int port) //指定服务端的端口号 public Socket accept() :侦听并接受连接,返回一个新的Socket对象,用于和客户端实现通信。该方法 会一直阻塞直到建立连接
服务端实现
public class ServerTCP {
public static void main(String[] args) throws IOException {
System.out.println("服务端启动 , 等待连接 .... ");
// 1.创建 ServerSocket对象,绑定端口,开始等待连接
ServerSocket ss = new ServerSocket(6666);
// 2.接收连接 accept 方法, 返回 socket 对象.
Socket server = ss.accept();
// 3.通过socket 获取输入流
InputStream is = server.getInputStream();
// 4.一次性读取数据
// 4.1 创建字节数组
byte[] b = new byte[1024];
// 4.2 据读取到字节数组中.
int len = is.read(b);
// 4.3 解析数组,打印字符串信息
String msg = new String(b, 0, len);
System.out.println(msg);
//5.关闭资源.
is.close();
server.close();
}
}
- 客户端实现
public class ClientTCP {
public static void main(String[] args) throws Exception {
System.out.println("客户端 发送数据");
// 1.创建 Socket ( ip , port ) , 确定连接到哪里.
Socket client = new Socket("localhost", 6666);
// 2.获取流对象 . 输出流
OutputStream os = client.getOutputStream();
// 3.写出数据.
os.write("你好么? tcp ,我来了".getBytes());
// 4. 关闭资源 .
os.close();
client.close();
}
}
第九章 函数式接口
- @FunctionalInterface注解
- 注解在接口上,给接口进行约束
- 匿名内部类会产生一个class文件,但Lambda表达式不会,有优势(速度快些吧)
- Lambda表达式延迟执行
- 常用的函数式接口
- 暂时不想学
第十章:流式编程
- 不想学了