Java SE痛点总结

2024-03-24 10:30
文章标签 java se 总结 痛点

本文主要是介绍Java SE痛点总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 循环边界
  • 访问修饰符
  • I/O
  • 对象的深拷贝
  • 反射

1 循环边界

无论是C++还是Java,基础笔试题里,总会冒出一个“以下循环执行了几次?”的奇妙问题,笔者将while语句实现n次循环的模式总结如下。
(a)

i = 0;
while (i < n) {...i++;
}

(b)

i = 1;
while (i <= n) {...i++;
}

(c)

while (n-- > 0) {...
}

(d)

while (--n >= 0) {...
}

2 访问修饰符

但凡涉及“访问修饰符”的编程语言,都是每个人心中无限的痛,笔者欲通过几段简单的代码,让大家了解Java的访问修饰符。

//同包同类
package com.baidu;public class A {public void pub() {System.out.println("public()");}protected void pro() {System.out.println("protected()");}void def() {System.out.println("default()");}private void pri() {System.out.println("private()");}public static void main(String[] args) {A aa = new A();aa.pub();aa.def();aa.pro();aa.pri();}// Output:// public()// default()// protected()// private()
}
//同包不同类
package com.baidu;public class B {public static void main(String[] args) {A aa = new A();aa.pub();aa.pro();aa.def();
//        java: pri() 在 com.baidu.A 中是 private 访问控制/*错误:aa.pri();*/}// Output:// public()// protected()// default()
}
//同包不同类继承
package com.baidu;public class C extends A {public void f() {pub();pro();def();/*pri();*/}
}class D {public static void main(String[] args) {C cc = new C();cc.f();}// Output:// public()// protected()// default()
}
//不同包继承
package com.google;import com.baidu.A;public class E extends A {public void g() {pub();pro();/*def();*//*pri();*/}
}class F {public static void main(String[] args) {E ee = new E();ee.g();}// Output:// public()// protected()
}
//不同包无任何关系的类
package com.google;import com.baidu.A;public class G {public static void main(String[] args) {A aa = new A();aa.pub();
//        java: pro() 在 com.baidu.A 中是 protected 访问控制
//        java: def()在com.baidu.A中不是公共的; 无法从外部程序包中对其进行访问
//        java: pri() 在 com.baidu.A 中是 private 访问控制/*aa.pro();*//*aa.def();*//*aa.pri();*/}// Output:// public()
}

结论如下:

publicprotecteddefaultprivate
同包同类
同包不同类-
同包不同类继承-
不同包继承--
不同包无任何关系的类---

3 I/O

3.1 File

File类包含了获得一个文件/目录的属性,以及对文件/目录进行改名和删除的方法。

文件名是一个字符串File类是文件名及其目录路径的一个包装类
注:该节示例省略了对异常的处理
对文件的操作

		/* 如果跨平台, 建议使用f3的形式 */File f1 = new File("E:/test.txt");File f2 = new File("E:\\test.txt");// File.separator属性 => 获取当前操作系统的路径分隔符File f3 = new File("E:" + File.separator + "test.txt");/* 常用方法 */System.out.println("文件是否可读: " + f1.canRead());System.out.println("文件是否可写: " + f1.canWrite());System.out.println("文件的名字: " + f1.getName());System.out.println("上级目录: " + f1.getParent());System.out.println("是否是目录: " + f1.isDirectory());System.out.println("是否是文件: " + f1.isFile());System.out.println("是否隐藏: " + f1.isHidden());System.out.println("文件的大小: " + f1.length());System.out.println("是否存在: " + f1.exists());System.out.println(f1 == f2);System.out.println(f1.equals(f2));// 与路径相关System.out.println("f1绝对路径: " + f1.getAbsoluteFile());System.out.println("f1相对路径: " + f1.getPath());System.out.println("toString: " + f1.toString());File f4 = new File("demo.txt");if (!f4.exists()) {f4.createNewFile();}System.out.println("f4绝对路径: " + f4.getAbsoluteFile());System.out.println("f4相对路径: " + f4.getPath());System.out.println("toString: " + f4.toString());f4.delete();

对目录的操作

		File f1 = new File("E:\\a");File f2 = new File("E:\\a\\b\\c");// 创建目录f1.mkdir();     // 创建单层目录f2.mkdirs();    // 创建多层目录// 删除目录 仅删除一层目录, 并且该目录下无文件(如果有文件, 则不会删除)f2.delete();// 查看String[] list = new File("E:/project/IdeaProjects").list();for (String s : list) {System.out.println(s);}File[] files = new File("E:/project/IdeaProjects").listFiles();for (File f : files) {System.out.println(f.getName());}

3.2 I/O流

File类可以非常方便地操作目录/文件,但用其获取文件/目录中的内容,似乎是不可行的。因此,Java提供了许多实现文件输入/输出的类。
注:I/O是Input/Output的缩写
图1 流的定义

图1 流的定义

SDK所提供的所有流类型位于包java.io内,其分别继承自以下四种抽象类型。

字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

按照功能不同又可将流分为节点流和处理流。
在这里插入图片描述

图2 节点流和处理流的形象表示
3.2.1 FileReader & FileWriter

顾名思义,这一组是用于读/写文本文件的。何为文本文件呢?.txt、.java、.h、.c、.cpp、.py、.go、.js等等均为文本文件。而诸如.doc、.ppt、.jpg、.png、.mp3、.mp4、.avi等为非文本文件,而对于非文本文件的读/写操作,应使用字节流。
本节以一个.txt文件的复制操作为例。

		FileReader fr = new FileReader(new File("E:/01.txt"));FileWriter fw = new FileWriter(new File("E:/02.txt"));int len = 0;char[] chars = new char[5];while ((len = fr.read(chars)) != -1) {fw.write(chars, 0, len);}fw.close();fr.close();
3.2.2 FileInputStream & FileOutputStream
		FileInputStream fis = new FileInputStream(new File("E:/01.vsdx"));FileOutputStream fos = new FileOutputStream(new File("E:/02.vsdx"));int len = 0;byte[] bytes = new byte[520];while ((len = fis.read(bytes)) != -1) {fos.write(bytes, 0, len);}fos.close();fis.close();

4 对象的深拷贝

在实际编程过程中,往往需要考虑深拷贝的问题,如果类成员变量中含有其他类成员,则所含类成员也需要实现Cloneable接口。考虑一种极端情况,如果类中所有变量均为其他类的实例,那逐个为其实现Cloneable接口并不现实。
本节以设计模式中的原型模式(Prototype)为例。原型模式的目的是从原型实例克隆出新的实例,对于那些有非常复杂的初始化过程的对象或者是需要耗费大量资源的情况,原型模式是更好的选择。
火影忍者中的鸣人有一项秘术叫做“多重影分身之术”,每一个影分身相对自己来说是独立的,所以设计鸣人的类如下:
Naruto.java

package cn.edu.xtu;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;public class Naruto implements Cloneable, Serializable {private int x; // 鸣人在战场上的横坐标private int y = 0;public Naruto(int x) {this.x = x;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void attack() {y++;}@Overridepublic Naruto clone() {try {ByteArrayOutputStream bout = new ByteArrayOutputStream();ObjectOutputStream out = new ObjectOutputStream(bout);out.writeObject(this);ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());ObjectInputStream in = new ObjectInputStream(bin);Naruto clone = (Naruto) in.readObject();return clone;} catch (Exception e) {e.printStackTrace();return null;}}
}

然后还要为其实现一个“产生鸣人的工厂”,即“多重影分身之术”。
NarutoFactory.java

package cn.edu.xtu;public class NarutoFactory {private static Naruto protoType = new Naruto(200);public static Naruto getInstance(int x) throws CloneNotSupportedException {Naruto clone = protoType.clone();clone.setX(x);return clone;}
}

当这两个类设计完之后,接下来就可以愉快的使用原型模式了。在主函数中,假设要创造500个鸣人,每个鸣人的横坐标满足集合 { x ∣ 0 ≤ x < 200 , x ∈ N } \{ x | 0 \leq x <200, x\in \mathbb{N}\} {x0x<200,xN}
Exec.java

package cn.edu.xtu;import java.util.ArrayList;
import java.util.List;
import java.util.Random;public class Exec {public static void main(String[] args) throws CloneNotSupportedException {List<Naruto> narutoes = new ArrayList<>();for (int i = 0; i < 500; i++) {Naruto naruto = NarutoFactory.getInstance(new Random().nextInt(200));narutoes.add(naruto);}}
}

请重点观察Naruto重写的clone方法,Naruto类实现了Serializable及Cloneable接口,依此操作,即使后续Naruto中要添加通灵兽或尾兽这些实例,clone方法也无需进行修改。

5 反射

这篇关于Java SE痛点总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/841320

相关文章

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏