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

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;