一、IO流
1.分类
1.按流的方向分类:
a.输入流:数据流向是数据源到程序(以InputStream、Reader结尾的流)。
b.输出流:数据流向是程序到目的地(以OutPutStream、Writer结尾的流)。
2.按处理的数据单元分类
a.字节流:以字节为单位获取数据,命名上以Stream结尾的流一般是字节流,顶级类InputStream、OutputStream。
b.字符流:以字符为单位获取数据,命名上以Reader/Writer结尾的流一般是字符流,顶级类Reader、Writer。
3.按处理对象不同分类
a.节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader等。
b.处理流:不直接连接到数据源或目的地,是“处理流”的流。通过对其他流的处理提高程序的性能,如BufferedInputStream、BufferedReader等。处理流也叫包装流。
2.File类
作用:
1.获取文件或者文件夹的属性
2.实现对文件、文件夹的创建和删除
例: File file = new File("c:/1.txt");
3.文件流:节点流
文件字节流:
1.FileInputStream
2.FileOutputStream
例:InputStream fileInputStream = new FileInputStream(file);
注意:
1.复制文件需要分别创建一个输入流和输出流完成文件读写
2.流使用完毕一定要关闭
3.需要创建一个中转站,借助循环和中转站完成复制
文件字符流:
1.FileReader
2.FileWriter
例: Reader fileReader = new FileReader(file));
注意:
字节流可以完成所有类型文件的复制(文本、音频、视频、图片、chm);字符流只可以完成文本文件的复制(txt、java) doc不是文本文件;字符流一般用来处理包含中文的文本文件
4.缓冲流:处理流
缓冲字节流:
1.BufferedInputStream
2.BufferedOutputStream
例:BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream)
注意:
1.流使用完必须关闭,缓冲流只需要关闭高层流即可,底层流不用手动关闭;因为高层的关闭方法就是把底层流关闭
2.刷新输出缓冲区:可以手动flush()
缓冲字符流:
1.BufferedReader
2.BufferedWriter
例:BufferedReader bufferedReader = new BufferedReader(fileReader);
优点:
1.速度快,简化编程
2.readLine()可以按行读取,底层是StringBuilder读到换行符,转成String返回
5.数据流和对象流:处理流
数据流:
1.DataInputStream
2.DataOutputStream
例:DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
注意:
1.只有字节流,都是处理流。
2.数据流只能操作基本数据类型和字符串
3.都是以二进制写入,需要对应输入流读取
对象流:
1.ObjectInputStream
2.ObjectOutputStream
例:ObjectInputStream objectInputStream = new ObjectInputStream(bufferedInputStream);
注意:
使用对象流读写引用类型的数据,需要相应类实现Serializable接口,否则会提示异常,提示没有序列化
6.序列化和反序列化
序列化 :Serialization 将对象的状态信息转换为可以存储或传输的形式的过程
内存——>硬盘:序列化 需要实现Serializable接口
硬盘——>内存:反序列化
二、反射
1.反射的入口——Class类
• Class类是Java反射机制的起源和入口
• Class类是所有类的共同的图纸
• Class类的对象称为类对象
2.使用反射和创建对象
//获取类的结构信息
Class clazz = Class.forName("com.dyq.test.Food");
//获取类的无参构造方法 括号内填写对应参数类型.class,可以获得对应有参构造
Constructor[] constructor1 = clazz.getConstructor();
//突破封装性的限制,即使是private、默认的也可以访问
constructor1.setAccessible(true);
//通过构造创建对象,无参
Object o1 = constructor1.newInstance();
//通过类名创建对象,无参
Object o = clazz.newInstance();
3.使用方法操作属性和执行方法
Class clazz = Class.forName("com.dyq.test.Food");
Object o = clazz.getConstructor().newInstance();
//获得属性
Field f1 = clazz.getField("color");
//使用带Declared的可以得到非公开的方法和属性
Field f2 = clazz.getDeclaredField("size");
//给属性赋值
f1.set(o,"绿色");
f2.setAccessible(true);//突破权限的控制
f2.set(o,5);
//获取方法
Method m1 = clazz.getMethod("eat");
Method m2 = clazz.getMethod("add",int.class);
//反射执行方法
m1.invoke(o);
m2.invoke(o.12);
三、注解
1.内置注解
@Override | 检查该方法是否是重载方法 |
@Deprecated | 标记过时方法 |
@SuppressWarnings | 指示编译器去忽略注解中声明的警告 |
JDK7开始添加的如下: | |
@SafeVarargs | Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告 |
@FunctionalInterface | Java 8 开始支持,标识一个匿名函数或函数式接口 |
@Repeatable | Java 8 开始支持,标识某注解可以在同一个声明上使用多次 |
2.元注解
@Retention | 用来约束注解的生命周期。有三个值,源码级别source,类文件级别class或者运行时级别runtime,若没有@Retention,则默认是 RetentionPolicy.CLASS |
@Target | 用来约束注解可以应用的地方(如方法、类或字段),若没有@Target,则该 Annotation 可以用于任何地方 |
@Documented | 标记这些注解是否包含在用户文档中 |
@Inherited | 指示注解类型被自动继承 |
@Retention补充:
1.SOURCE:注解将被编译器丢弃(该类型的注解信息只会保留在源码里,源码经过编译后,注解信息会被丢弃,不会保留在编译好的class文件里)
2.CLASS:注解在class文件中可用,但会被VM丢弃(该类型的注解信息会保留在源码里和class文件里,在执行的时候,不会加载到虚拟机中)。
3.RUNTIME:注解信息将在运行期(JVM)也保留,因此可以通过反射机制读取注解的信息(源码、class文件和执行的时候都有注解的信息),如SpringMvc中的@Controller、@Autowired、@RequestMapping等。
@Target补充:
/**标明该注解可以用于类、接口(包括注解类型)或enum声明*/
TYPE,
/** 标明该注解可以用于字段(域)声明,包括enum实例 */
FIELD,
/** 标明该注解可以用于方法声明 */
METHOD,
/** 标明该注解可以用于参数声明 */
PARAMETER,
/** 标明注解可以用于构造函数声明 */
CONSTRUCTOR,
/** 标明注解可以用于局部变量声明 */
LOCAL_VARIABLE,
/** 标明注解可以用于注解声明(应用于另一个注解上)*/
ANNOTATION_TYPE,
/** 标明注解可以用于包声明 */
PACKAGE,
/**
* 标明注解可以用于类型参数声明(1.8新加入)
* @since 1.8
*/
TYPE_PARAMETER,
/**
* 类型使用声明(1.8新加入)
* @since 1.8
*/
TYPE_USE
3.自定义注解
public @interface MyAnnoation {
int id() default 0;
}