Java注解、文件IO以及匿名函数

文章目录

  • 1. 注解
    • 1.1 自定义注解
    • 1.2 元注解
      • 1.2.1 @Target
      • 1.2.2 @Retention
    • 1.3 注解的解析
  • 2. 文件IO
    • 2.1 非流式文件类
    • 2.2 流式文件类
      • 2.2.1 字节输入流
      • 2.2.2 字节输出流
      • 2.2.3 字符输入流
      • 2.2.4 字符输出流
  • 3. 匿名
    • 3.1 lambda表达式
    • 3.2 方法引用

1. 注解

注解可以在类、方法、构造器、成员变量、参数等地方进行使用,其作用是让其他程序根据注解的信息来决定怎么执行程序。

1.1 自定义注解

自定义注解的形式如下:

public @interface 注解名{public 属性类型 属性名() default 默认值;
}

特殊属性名:value。 如果注解中只有一个 value 属性,那么使用注解时, value 名称可以不写。

创建一个 Mytest1 的注解,注解源码如下:

public @interface Mytest1 {String a();boolean b() default true;String[] c();
}

使用注解时,可以在注解里面传值,如下,

@Mytest1(a="练习生", c={"唱", "跳", "rap", "篮球"})
public class Test1 {public static void main(String[] args) throws Exception {}
}

1.2 元注解

元注解即修饰注解的注解。

常用的元注解有 @Target 以及 @Retention

1.2.1 @Target

该注解声明被修饰的注解只能在哪些位置使用,使用注解时使用形式为 @Target(Element.TYPE) ,其中 TYPE 字段可变,可选值如下:

  1. TYPE :作用于类、接口
  2. FIELD :作用于成员变量
  3. METHOD :作用于成员方法
  4. PARAMETER :作用于方法参数
  5. CONSTRUCTOR :作用于构造器
  6. LOCAL_VARIABLE :作用于局部变量
  7. ANNOTATION_TYPE :作用于注解
  8. PACKAGE :作用于

该元注解可以作用于多个位置,如 @Target({Element.TYPE, Element.FIELD})

1.2.2 @Retention

该注解声明注解的保留周期,使用形式为 @Retention(RetentionPolicy.RUNTIME) ,其中 RUNTIME 字段可选值如下:

  1. SOURCE :只作用于源码阶段,字节码文件中不存在
  2. CALSS默认值,保留到字节码文件阶段,运行阶段不存在
  3. RUNTIME :一直保留到运行阶段,开发时常用

1.3 注解的解析

有时候加了一行注解后就能够实现很多的功能,看上去注解十分强大,其实不然,注解只是一个获取值的接口,注解本身并不能进行值的操作与解析功能,如果要对注解进行解析,那么需要在另一个文件中利用反射的方式来对其进行解析。

解析注解时,要注意的是,要解析谁上面的注解,就应该先拿到谁。比如要解析类上面的注解,就应该先获得加载类,获取 Class 对象,再通过 Class 对象解析上面的注解;要解析成员方法上面的注解,就应该先获取该成员方法上面的 Method 对象,再通过 Method 对象解析上面的注解。

Class,Method,Field,Constructor 都实现了 AnnotatedElement 接口,故都有解析注解的能力,解析注解主要使用的方法如下:

AnnotatedElement 提供的解析注解的方法
public Annotaion[] getDeclaredAnnotations()获取当前对象上面的注解
public T getDeclaredAnnotations(Class<T> annotationClass)获取指定的注解对象
public boolean isAnnotationPresent(Class<Annotation> annotationClass)判断当前对象上是否存在某个注解

比如我们可以对上面的 Test1 类的 @Mytest1 注解进行解析,解析如下

public class AnalyzeAnnotation {public static void main(String[] args) {Class c = Test1.class;// 判断是否存在Mytest1注解if(c.isAnnotationPresent(Mytest1.class)){// 获取注解对象Mytest1 mytest1 = (Mytest1)c.getDeclaredAnnotation(Mytest1.class);System.out.println(mytest1.a());System.out.println(mytest1.b());System.out.println(Arrays.toString(mytest1.c()));}}
}

2. 文件IO

2.1 非流式文件类

在Java语言的 java.io 包中,由File类提供了描述文件和目录的操作与管理方法。但 File 类不是 InputStreamOutputStreamReaderWriter的子类,因为它不负责数据的输入输出,而专门用来管理磁盘文件与目录。

File 类的初始化如下:

// 根据路径来获取文件对象,这里也可以是一个文件夹
File file = new File("ikun.txt");

其常用的方法如下:

方法说明
boolean createNewFile创建一个新的文件 如果存在这样的文件,就不创建了
boolean mkdir创建文件夹 如果存在这样的文件夹,就不创建了 注意这个方法只能创建单层目录 如果创建多层目录得一层一层创建
boolean mkdirs创建文件夹,如果父文件夹不存在,会帮你创建出来 可以创建多层目录 当然也可以创建单层目录
boolean delete删除文件或者文件夹(文件夹是空文件夹才能删除!如果这个文件夹里面有文件,则不能删除! 要删除一个文件夹,该文件夹内不能包含文件或者文件夹)
boolean renameTo(File dest)把文件重命名为指定的文件路径(如果路径名相同,就会改名.如果路径名不同,就是改名并剪切)
boolean isDirectory()判断是否是目录
boolean isFile()判断是否是文件
boolean exists()判断是否存在
boolean canRead()判断是否可读
boolean canWrite()判断是否可写
boolean isHidden()判断是否隐藏
boolean isAbsolute()判断是否使用的是绝对路径
File getAbsolutePath()获取绝对路径
String getParent()返回此抽象路径名父目录的路径名字符串,如果此路径名没有指定父目录,则返回 null.
File getParentFile()返回此抽象路径名父目录的抽象路径名,如果此路径名没有指定父目录,则返回 null.
long getTotalSpace()返回此抽象路径名指定的分区大小。 返回总容量 单位字节
long getFreeSpace()返回此抽象路径名指定的分区中未分配的字节数。返回剩余容量 单位字节
String getName()获取名称
long length()获取长度.也就是文件大小,有多少字节数
long lastModified()获取最后一次的修改时间,单位为毫秒
String[] list()获取指定目录下的所有文件或者文件夹的名称,然后放入字符串数组
File[] listFiles()获取指定目录下的所有文件或者文件夹,然后放入File数组

2.2 流式文件类

流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种:

  1. 字节流:数据流中最小的数据单元是字节
  2. 字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。

注意,以下的输入输出流都是相对内存而言的,即输入流是输入到内存,也就是读文件,输出流是从内存输出,也就是写文件。

2.2.1 字节输入流

字节输入流主要使用的是 FileInputStream 函数。

该函数的构造函数有两个形式,分别为 FileInputStream(String name), FileInputStream(File file) ,示例如下:

//直接通过文件地址初始化
FileInputStream fis = new ileInputStream("D:/test/test1.txt");//通过File对象初始化
File file = new File("D:/test/test1.txt");
FileInputStream fis = new FileInputStream(file)

该读取的形式有两个主要如下:

read()读取一个字节(返回对应字节的ascii码值)
read(byte b[])根据字节缓冲数组的长度,进行读取(返回读取的字节数)

读取示例如下:

// 方式一
FileInputStream fis = new FileInputStream("ikun.txt");
while (true){//read() 方法:从输入流对象中,一次读取一个字节(返回的是对应字节的ascii码值,int类型)int hasRead = fis.read();//当读取到末尾,返回-1,代表文件读取结束if(hasRead == -1){break;}System.out.print((char) hasRead);//打印文件中字符的ascii值//转化为字符:KH96abcdefghijk
}//最后一定要关闭资源
fis.close();// 方式二
FileInputStream fis = new FileInputStream("D:/test/test1.txt");
//带缓冲字节数,根据字节缓冲数组的长度,进行读取
byte[] bytes = new byte[5];
//正确写法
int hasRead = 0;
while((hasRead = fis.read(bytes)) > 0){//每次读取的内容System.out.println(new String(bytes,0,hasRead));
}
fis.close();

2.2.2 字节输出流

字节输出流主要使用的是 FileOutputStream 函数。

其构造函数如下:

FileOutputStream(File file, boolean append)
FileOutputStream(String name)
FileOutputStream(String name, boolean append)

与输入流的构造函数类似,不过写入的文件不一定要存在,如果文件不存在,会自动创建一个空的文件;其后的 append 参数表示是否以追加的方式写入文件,默认值为 false 即覆盖,若设为 true 即为追加。

该写入的形式有两个主要如下:

write()将b.length个字节从指定字节数组写入此文件输出流中
write(byte b[], int off, int len)将指定字节数组中从偏移量off开始的len个字节写入此文件输出流

示例如下:

String string = "Ikun班,正在学习文件输出流,输出文件2";//JDK1.7以后,只需将资源初始化放在try()里面就可以不用手动关闭流资源,推荐使用;
try(FileOutputStream fos =  new FileOutputStream("D:/test/test2.txt",true)){//将字符串转成字节数组,写入目标文件fos.write(string.getBytes());//手动刷新缓冲区fos.flush();}catch (IOException e){e.printStackTrace();
}

2.2.3 字符输入流

Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。

其构造函数如下:

FileReader(File file)
FileReader(String fileName)

读取如下:

read()按单个字符读取
read(char cbuf[])按字符数组长度读取

示例如下:

try(//初始化字符读取流FileReader frd =   new FileReader("ikun.txt");
){//定义一个可变字符串对象StringBuilder sbd = new StringBuilder();//定义缓冲字符数组char[] chars = new char[5];int hasRead = 0; //读取到的字符长度while((hasRead = frd.read(chars))>0){sbd.append(new String(chars,0,hasRead));}//输出文件内容System.out.println("文件全部内容:\n"+sbd.toString());System.out.println("文件读取成功!");} catch (FileNotFoundException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
}

2.2.4 字符输出流

初始化如下:

FileWriter(String fileName)
FileWriter(File file, boolean append)
FileWriter(String fileName, boolean append)

其含义同字节输出流函数。

示例如下:

try( FileWriter fwr=  new FileWriter("D:/test/test2.txt")){//定义写入文件String string = "KH96,正在学习字符流写入文件";//直接写入目标文件fwr.write(string);//刷新缓冲区fwr.flush(); //一定要刷新缓冲区System.out.println("字符流写入成功!!!");
}catch (Exception e){e.printStackTrace();
}

3. 匿名

3.1 lambda表达式

java中的 lambda 表达式的一般格式如下:

(参数列表) -> {lambda表达式体}

lambda 表达式的情况可分为以下几种:

  1. 无参数,无返回值

    Runnable run = () -> {System.out.println("lambda表达式实现");};
    

    如果执行语句只有一行,可以省略”{}“:

    Runnable run = () -> System.out.println("lambda表达式实现");
    
  2. 有一个参数,无返回值

    Consumer<String> consumer = (String s) -> {System.out.println(s);};
    

    参数类型可以省略,因为编译器会根据上下文环境推断出参数的类型,也叫做类型推断。这里指定了泛型为String。

    而且只有一个参数时,参数列表的”()“也可以省略。所以可以这么写:

    Consumer<String> consumer =  s -> System.out.println(s);
    
  3. 有多个参数,有返回值

    Comparator<Integer> comparator1 = (o1,o2) -> {System.out.println(o2);return Integer.compare(o1,o2);
    };
    
  4. 只有一条执行语句且有返回值

    Comparator<Integer> comparator1 = (o1,o2) -> {return Integer.compare(o1,o2);
    };
    

    如果有返回值时只有一条执行语句,那么”return“可以省略。

    Comparator<Integer> comparator1 = (o1,o2) -> Integer.compare(o1,o2);
    
  5. 将Lambda表达式作为参数传递

    Thread thread = new Thread(() -> {System.out.println("lambda表达式实现");
    });
    

    为了将Lambda 表达式作为参数传递,接收Lambda 表达式的参数类型必须是与该Lambda 表达式兼容的函数式接口的类型。比如上面代码中的Lambda表达式的作用就是创建了一个Runnale对象,而new Thread()的参数可以是一个Runnable对象。

3.2 方法引用

方法引用可以看做是lambda函数的语法糖,其引用与Lambda表达式对应如下:

类型方法引用Lambda表达式
Class::staticMethod(args) -> Class.staticMethod(args)
实例方法引用Instance::instanceMethod(args) -> Instance.instanceMethod(args)
对象方法引用Class::InstanceMethod(instance, args) -> Class.instanceMethod(args)
构造方法引用Class::new(args) -> new Class(args)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/59267.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6.oracle中listagg函数使用

1. 作用 可以实现行转列&#xff0c;将多列数据聚合为一列&#xff0c;实现数据的压缩 2. 语法 listagg(measure_expr&#xff0c;delimiter) within group ( order by order_by_clause); 解释&#xff1a; measure_expr可以是基于任何列的表达式 delimiter分隔符&#xff0c…

HTML学习笔记02

HTML笔记02 页面结构分析 元素名描述header标题头部区域的内容&#xff08;用于页面或页面中的一块区域&#xff09;footer标记脚部区域的内容&#xff08;用于整个页面或页面的一块区域&#xff09;sectionWeb页面中的一块独立区域article独立的文章内容aside相关内容或应用…

红黑树(AVL树的优化)上

红黑树略胜AVL树 AVL树是一颗高度平衡搜索二叉树&#xff1a; 要求左右高度差不超过1&#xff08;严格平衡&#xff09; 有的大佬认为AVL树太过严格&#xff0c;对平衡的要求越严格&#xff0c;会带来更多的旋转&#xff08;旋转也还是会有一定的消耗&#xff01;&#xff01;…

java多线程之线程通信

java多线程文章 java多线程之线程创建和状态 java多线程之FutureTask、Future、CompletableFuture java多线程之线程池 java多线程之线程通信工具类 合理的使⽤Java多线程可以更好地利⽤服务器资源。⼀般来讲&#xff0c;线程内部有⾃⼰私 有的线程上下⽂&#xff0c;互不⼲…

WordPress使用子主题插件 Child Theme Wizard,即使主题升级也能够保留以前主题样式

修改WordPress网站样式&#xff0c;主题升级会导致自己定义设置的网站样式丢失&#xff0c;还需要重新设置&#xff0c;很繁琐工作量大&#xff0c;发现在WordPress 中有Child Theme Wizard子主题插件&#xff0c;使用Child Theme Wizard子主题插件&#xff0c;即使主题升级&am…

使用devsidecar 软件解决 git因网络问题报错的

上链接&#xff1a; https://github.com/docmirror/dev-sidecar/releases 下载你系统对应的版本 安装后根据教程设置即可 解决了git提交、拉取时报以下错误&#xff1a; Failed to connect to github.com port 443 after 21051 ms: Couldnt connect to server Recv failur…

2023年下半年西安/广州/深圳软考(中/高级)开班啦!!!

软考是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资格考试。 系统集成项…

智慧校园用电安全解决方案

随着科技的不断发展&#xff0c;智慧校园建设逐渐成为了教育行业的一大趋势。在这个过程中&#xff0c;电力系统作为校园基础设施的重要组成部分&#xff0c;其安全、稳定、高效的运行显得尤为重要。下面小编来为大家介绍下智慧校园用电安全解决方案吧! 一、智慧校园电力系统现…

前端知识总汇

前端知识总汇 HTML 超文本标记语言 注释 <!--单行注释--> <!-- 多行注释 --> 由于 HTML 代码杂乱无章&#xff0c;我们习惯性的用注释来划定区域方便后续的查找HTML 的文档结构 <!DOCTYPE html> <html lang"en"><!-- 定义配置给浏览…

抖店无货源和工厂直发有什么区别?聊下无货源的概念和做店思路

我是王路飞。 最近收到了几条私信&#xff0c;都是关于做抖店的&#xff0c;其中有一条吸引了我的兴趣。 他问的是&#xff1a;抖店的无货源和工厂直发有什么区别吗&#xff1f; 说实话&#xff0c;这个问题&#xff0c;我一开始是不打算回复的&#xff0c;因为没有意义。 …

C# task多线程创建,暂停,继续,结束使用

1、多线程任务创建 private void button1_Click(object sender, EventArgs e) //创建线程{CancellationToken cancellationToken tokensource.Token;Task.Run(() > //模拟耗时任务{for (int i 0; i < 100; i){if (cancellationToken.IsCancellationRequested){return;…

[C++ 网络协议] 多进程服务器端

具有代表性的并发服务器端实现模型和方法&#xff1a; 多进程服务器&#xff1a;通过创建多个进程提供服务。✔ 多路复用服务器&#xff1a;通过捆绑并统一管理I/O对象提供服务。 多线程服务器&#xff1a;通过生成与客户端等量的线程提供服务。 目录 1. 进程的概念及应用 1.…

24 - form表单验证 - bootstrap结合使用

一. flask中bootstrap的使用 16- flask-bootstrap模板的使用_一个微不足道的bug的博客-CSDN博客 二. form结合bootstrap使用 (1). form.py 进行表单验证 from flask_wtf import FlaskForm from flask_wtf.file import FileField, FileRequired, FileAllowed from wtforms impo…

统计学补充概念-16-支持向量机 (SVM)

概念 支持向量机&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;是一种用于分类和回归的机器学习算法。SVM的主要目标是找到一个最优的超平面&#xff0c;可以将不同类别的数据样本分开&#xff0c;同时使得支持向量&#xff08;离超平面最近的样本点&#xf…

CTFhub-文件上传-前端验证

burp 抓包 --> 重发--> 查看源代码 用 GodZilla 生成木马 文件名为 1.php.jsp 上传-->抓包-->改包 (删掉 .jpg) --> 点击 放行 木马文件位置为&#xff1a;http://challenge-f0531d0c27641130.sandbox.ctfhub.com:10800/upload/1.php 用 蚁剑连接 ctfhub{4743b…

数组中的第K个最大元素

题目链接 数组中的第K个最大元素 题目描述 注意点 需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素 解答思路 本题可以使用快速排序、堆排序或优先队列解决&#xff0c;快排可以比较快速找到某个元素在数组中排序后的位置&#xff0c;所以找…

Linux内核数据结构 散列表

1、散列表数据结构 在Linux内核中&#xff0c;散列表&#xff08;哈希表&#xff09;使用非常广泛。本文将对其数据结构和核心函数进行分析。和散列表相关的数据结构有两个&#xff1a;hlist_head 和 hlist_node //hash桶的头结点 struct hlist_head {struct hlist_node *first…

最简单vue获取当前地区天气--高德开放平台实现

目录 前言 一、注册成为高德平台开发者 二、注册天气key 1.点击首页右上角打开控制台 2.创建新应用 三、vue项目使用 1.打开vue项目找到public下的index.html&#xff0c;如果是vue3的话直接在主目录打开index.html文件就行&#xff0c;主要就是打开出口文件 ​编辑 2.根据高德…

HTTPS协议原理

目录 前言 1.理解加密和解密 2.为什么要加密 3.常见的加密方式 3.1对称加密 3.2非对称加密 4.数据摘要和数据指纹 5. 数字签名 6.HTTPS的加密策略 6.1只使用对称加密 6.2使用非对称加密 6.2.1服务端使用非对称加密 6.2.2双方都使用非对称加密 6.3对称加密非对称加…

OLED透明屏显示技术:未来显示科技的领航者

OLED透明屏显示技术是一种创新性的显示技术&#xff0c;它的特殊性质使其成为未来显示科技的领航者。 OLED透明屏具有高对比度、快速响应时间、广视角和低功耗等优势&#xff0c;同时&#xff0c;其透明度、柔性和薄型设计使其成为创新设计的理想选择。 本文将深入探讨OLED透…