JAVA
JAVA学习笔记
Debris
-
语句
FILE f=new FILE("Grades.txt");
在IDEA中运行时,读取的目标文件不一定是源码所在目录下的"Grades.txt",而是源码类所属的父模块中最高级的模块目录下的"Grades.txt",但直接用系统shell运行时能正确读取源码目录下的文件。
-
"FileOutputStream"等文件流创建语句必须写在"try...catch"语句块中,否则会报错
-
Scanner.useDelimiter(pattern)
中的pattern是正则表达式
pattern="[...]"
用多个分隔符代替...即可,注意最好加上
\n\r
(换行回车和空格) -
ObjectOutputStream
所写入的数据以"ISSO-8859-1"编码 -
javac -encoding utf-8 DST
以UTF-8编码编译目标类。输入内容的正确编码格式取决于输入模块的选择了什么编码进行内容输入,内容能否以正确的编码格式被读取取决于文件以什么编码格式被保存(读取),若是保存格式不对就会出现乱码。 -
Char 类型数组"a",使用:
System.out.printlb(a);
不会输出其引用信息,而是会输出数组字符内容。
Sytem.out.println(""+a);
与字符串做并置运算(+)时会输出其引用。
-
Java 标识符由字母(包括各种语言的常规字符)、美元符号、下划线与数字组成,开头不能为数字。
-
Java 有 8 种基本数据类型:
boolean, byte, short, int, long, float, double, char
。类型精度从低到高:
byte<short<char<int<long<float<double
-
查看表达式结果的类型:
Object _obj = <EXP>; System.ot.print(_obj.getClass().toString());
-
算术表达式的结果类型最低精度为 int,实际结果精度取运算符操作数中的最高。若式子中含有变量则检查类型,若只是常量运算检查数值。自增自减除外。
因此有如下特性:
int n=1; short c = n+1; // Error short a = 5+4; a = a-5; // Error a = --a;
-
var
局部类型推断:public class Test{ Test(){ var a=14; // 推断为 int var b=1.20f; // 推断为 float var c='c'; // Error,无法推断 } }
-
无名包的类只要放在同一个目录下,可被视为在同一个包下。但无名包的类无法被不同包的其他类引用。
-
可变参数:
void my_print(int ... x){ for(int t:x){ System.out.print(t); } for(int i=0; i<x.length; i++){ System.out.print(x[i]); } }
-
静态块:
class AAA{ static { System.out.println("I'm the static block in the Class AAA."); } } public class E{ static{ System.out.println("I'm the static block which is called first."); } public static void main(String args[]){ AAA a = new AAA(); // AAA 的字节码进入内存 System.out.println("I'm trying to understand the concept of static block."); } }
-
只有 abstract 类中可以有 abstract 方法;
不允许同时用
final,abstract
修饰一个方法或类;不允许用
static, private
修饰 abstract 方法,其权限必须高于private
。 -
对于类继承中的『上转型对象』而言,如果子类重写了父类的静态方法,则上转型对象只能调用父类的静态方法,不能调用子类重写的静态方法。如果子类重写的是非静态方法,则上转型对象会调用其重写后的方法。
子类在重写父类方法时,不能把类方法(静态方法)重写成实例方法,或者把实例方法重写为类方法。但可以把父类的非抽象方法重写成抽象方法(什么?)。
子类在重写父类方法时,方法的权限只能提高不能降低。
-
super
也无法调用所继承父类的private
方法,这意味着一个构造函数全是private
权限的类不能有子类。 -
instanceof
为双目运算符,判断左侧的对象是否为右侧的类(或者其子类或者实现了接口的类)实例化获得的。
Solution
0.4 无限循环小数
由于 0.4 用二进制表示时是无限循环小数,因此有以下特性:
float x = 0.4f;
double y = 0.4;
x 中实际存储的是 Float 类型的常数 0.4000000059604654(保留16位),存储在 y 中的是 Double 类型的常数 4e-16,因此 y 中的值小于 x 中的值。
Qst:Float 只保存 8 位有效数字,而 5 出现在第 9 位,那为什么与 y 比较时还是大于 y?四舍五入?
Ans:Float 与 Double 比较时,前者被转换成 Double 类型,由于保存的是 0.4f 也就是 FLoat 常数,因此转换时进行了精确的计算,将第九位开始的小数也保存了下来,再与 Double 类型的常数 0.4 进行比较。所以有:
jshell> 0.4f - 0.4; $33 ==> 5.960464455334602E-9 jshell> 0.4f - 0.4f; $34 ==> 0.0
访问权限
public | protected | default | private | |
---|---|---|---|---|
同类的其他成员 | 1 | 1 | 1 | 1 |
同包其他类(包括子类) | 1 | 1 | 1 | |
不同包的子类 | 1 | 1 | ||
不同包的非子类 | 1 |
1 表示可以访问。
对于构造函数,也可以有以上四种访问权限。new Object()
可以看作是显式访问并调用了类 Object 的某个构造函数,由此可以判断其应用场合与类的成员方法并无区别。如果设置为 private,则只能在本类中调用。
常用类
String
常用函数
"小鸟fly".length() == 5; // true
<String-1>.equals(<String-2>); // 比较实体是否相等
.equalsIgnoreCase(); // 比较时忽略大小写区别
<String-1>.startsWith("abc"); // 判断字符串前缀,是则 True
.endsWith(""); // 判断字符串后缀
<String-1>.compareTo(<String-2>); // 按照字典序比大小,若大于 <String-2> 返回正值。
.compareToIgnoreCase(); // 忽略大小写
.contains(); // 是否包含子串
.indexOf(<String>, <StartPoint>); // 检索字符串首次出现的开始下标
.lastIndexOf(...); // 检索字符串最后一次出现的开始下标
.substring(<startPoint>, <endPoint>); // 获取子串,注意参数二是结束下标
.trim(); // 返回一个新的 String,去掉前后空格
<String-1>.replaceAll(<regex>, <String-2>); // 根据正则表达式替换整个字符串, 会返回新的 String
String split_str = <String>.split(<regex>); // 根据正则表达式匹配分隔符,分割字符串并返回字符串数组;分隔符左侧可为空,右侧不行
类型转换:
// String -> Integer, Double...
Integer.parseInt("5");
Double.parseDouble("5.5");
// Intger,Double... -> String
String.valueOf(5);
""+23; // 并置运算
进制转换:
// 二进制、八进制、十六进制
Integer.toBinaryString(15); // "1111"
Integer.toOctalString(int);
Integer.toHexString(int);
Long.toBinaryString(Long);
Long.toOctalString(Long);
Long.toHexString(Long);
字符串与字符数组的转换
String s = "一二三四五六七八九";
char [] a,c;
a = new char[4];
s.getChars(3,6,a,0); // 将 s 中 3-5 处的字符放到 a 数组中从 0 开始的位置上
c = "你说得对,但是".toCharArray(); // 直接将字符串转换为数组。
字符串与字节数组的转换
byte[] d = "你好".getBytes("utf-8"); // [ -60, -29, -70, -61 ]
d.length; // 4
String hao = new String(d,2,2); // "好"
String highBytes = Integer.toBinaryString(d[3]);
highBytes = highBytes.substring(highBytes.length()-8); // 取后 8 位
String lowBytes = Integer.toBinaryString(d[2]);
lowBytes = lowBytes.substring(lowBytes.length()-8);
System.out.println(highBytes+" "+LowBytes); // 11000011 10111010
正则表达式
元字符 | 意义 |
---|---|
. |
任何字符 |
\. |
. 字符 |
\d |
0~9 中任何一个数字 |
\D |
任何一个非数字 |
\s |
空各类字符,\t, \n, \x0B, \f, \r, \x20 |
\S |
非空格类字符 |
\w |
可用于标识符的字符,不包括美元符号和非 ASCII 码字符 |
\W |
不能用于标识符的字符 |
\p{Lower} |
小写字母 a~z |
\p{Upper} |
大写字母 A~Z |
\p{ASCII} |
ASCII 码字符 |
\p{Alpha} |
字母 |
\p{Digit} |
数字字符,0~9 |
\p{Alnum} |
字母或者数字 |
\p{Punct} |
标点符号,``! , " # $ % & ' ( ) * + - . / : ; < = > ? @ [ ] \ ^ _ ` { |
\p{Graph} |
可视字符:\p{Alnum} ,\p{Punct} |
\p{Print} |
可打印字符 |
\p{Blank} |
空格或制表符:\t |
\p{Cntrl} |
控制字符:[\x00-\x1F\x7F] |
允许嵌套方括号,进行差、并、交运算:[a-z&&[^bc]]
,[a-d[m-p]]
,[a-z&&[def]]
限定修饰符
带限定修饰符的模式 | 意义 |
---|---|
X? |
X 出现一次或零次 |
X* |
X 出现零次或多次 |
X+ |
X 出现一次或多次 |
X{n} |
X 恰好出现 n 次 |
X{n,} |
X 至少出现 n 次 |
X{n,m} |
X 出现 n 次至 m 次 |
常用正则表达式
正则表达式(字面量) | 意义 |
---|---|
-?[1-9]\\d* |
整数字符序列 |
-?[0-9][0-9]*[.][0-9]+ `-?(0? |
[1-9]\d)[.]\d` |
\\w+@\\w+(\\.[a-z]+)+ |
邮箱 |
[1-9]\\d{16}\p{Alnum} |
中国公民身份证 |
`[1-9]\d{3}[-./](0?[1-9] | 1[012])[-./](0?[1-9] |
Exception
NumberFormatException // 非法数字字符 - Double.parseDouble(<String>); | new BigInteger(<String>>);
UnsupportedEncodingException // 不支持的编码格式 - String.getBytes()
InputMismatchException // 读入内容类型不匹配 - <Scanner>.nextInt()
JAVA 常用包
总览
java.util
HashMap
regex.
Pattern
Matcher
Random
java.io
FileInputStream, FileOutputStream
ObjectInputStream, ObjectOutputStream
IOException
java.net
URL
java.lang
(自动被 JAVA 导入)
reflect.
Field
System
Math
java.math
BigInteger
java.time
LocalDate
LocalTime
LocalDateTime
详情
-
StringTokenizer
StringTokenizer st = new StringTokenizer(<String>, <delim-String>) st.hasMoreTokens(); st.countTokens(); st.nextToken();
<delim-String>
传入分隔符,以所有分隔符任意长的任意排列为单词分隔符。 -
Scanner
Scanner scanner = new Scanner(<String>); scanner.useDelimiter(<regex-string>); // 以正则表达式为分隔符,分割字符串 scanner.hasNext(); scanner.next(); // 返回字符串|浮点数|整数 .nextDouble(); .nextInt();
-
StringBuffer
可变字符串new StringBuffer(<String>); <StringBuffer>.append(); // 连接字符串 .charAt(<int-n>); // 返回 char .reverse(); // 返回 StringBuffer .delete(<int-startIdx>, <int-endIdx>);
-
Pattern, Matcher
Pattern p = Pattern.compile(<regex-string>); // 生成正则匹配模式 Matcher m = p.matcher(<source-string>); // 输入数据源 while(m.find()){ // 寻找下一个匹配的字符串 String item = m.item(); // 获取找到的字符串 int beg = m.start(); int end = m.end(); // 返回找到字符的开始位置和结束位置 }
-
LocalDate, LocalDateTime, LocalTime
localDate
为完整日期:LocalDate.now(); // 返回当前时间 LocalDate.of(1988, 12, 16); // 返回指定时间 <LocalDate>.getDayOfMon(); // 月中的日期号码,如16号 .getMonthValue(); // 月号数值 .getMonth(); // 月的枚举值,FEBRUARY .getDayOfWeek(); // 星期枚举值,SUNDAY .isLeapYear(); // 是否为闰年 .plusMonths(); // 返回一个新的日期对象,为当前日期加上指定月数后的新日期 .compareTo(); // 按年月日顺序比较,当某项不同时直接返回该项的差值,正大负小 .until(<end-date>, <unit>); // 计算到<end-date>的日期差,<unit>传入枚举类型来标记差值的单位,如 ChronoUnit.DAYS 是天数 .isBefore(<date-1>); // 判断是否在指定日期之前
LocalTime
为完整时间,LocalDateTime
为完整日期+时间。格式化
String.format("%ty 年 %tm 月 %td 日", <LocalDate>,<LocalDate>,<LocalDate>); // 结果为 2022 年 02 月 17 日 String.format("%ta-%<tm-%td", <LocalDate>); // 2022-02-17, %< 为前缀表示与前一个格式符处理同一个变量 // %tA-Sunday %tH-24小时 %tM-分 %tS-秒
更换不同地区的风格
format(Local locale, <String-pattern>, <LocalDate--list>); // 对于 Locale 表示地域,US-美国
-
java.lang.Math
Math.E // 自然对数 .PI // 圆周率 .abs(<double>); .max(); .random(); // [0,1)的随机数 .pow(a,b); // a的b次方 .sqrt(); .log(); .sin(); .asin(); .ceil(); // 向上取整,返回Double .floor(); // 向下取整,返回Double .round(); // 四舍五入
-
java.math.BigInteger
大整数类。 -
java.util.Random
随机数类new Random(<Long-seed>); <Random>. int nextInt(); // 随机整数 int nextInt(<int-n>); // [0,n)的随机整数 Double nextDouble(); // [0,1.0) Boolean nextBoolean();
-
数字格式化
%d - 十进制整数 %o - 八进制整数 %x - 小写十六进制整数 %X - 大写 Hex %f - 十进制浮点数,默认6位小数 %e - 科学计数法 %E - E 大写 %mf|%-mf - 输出宽度为m,在左侧|右侧补空格 %% - 转义 %
-
java.lang.Class
类
<Object>.
class getClass(); // 获取存放当前类相关信息的 class 类
<Class>.
String getName();
java.lang.reflect.Constructor[] getDeclaredConstructors(); // 全部构造方法
Constructor<?> getDeclaredConstructor(); // 获取默认无参构造函数
java.lang.reflect.Field[] getDeclaredFields(); // 全部成员变量
java.lang.reflect.Method[] getDeclaredMethods(); // 全部方法
Class.
Class<?> forName(<String>); // 返回指定类,传入带包名的完整类名
<Constructor>.
Object newInstance(); // 返回一个新对象实例
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具