JavaSE学习笔记
前情提要
学习路径
学习方法
多写,多练,多分享思考,贵在坚持。
即输出代码,输出笔记博客,费曼教学,能把学到的东西讲清楚,让听的人明白,多总结思考。
教授知识只是基础,还要对别人的人生观价值观产生积极正向的影响。这样反而更能促进学习者的学习兴趣和深入理解。
为什么要博客?
- 总结和思考
- 提升文笔组织能力
- 提升学习总结能力
- 提升逻辑思维能力
- 帮助他人,分享知识,结交朋友
自建博客
- wordpress
- typecho
markdown基本语法
-
# 一级标题
-
## 二级标题
-
##### 五级标题
-
- 列表第一项
-
- 列表第二项
-
\1. 有序列表第一项
-
\2. 有序列表第二项
-
-
斜体
-
粗体
-
> 引用段落
-
``` 代码块 ```
冯诺依曼体系结构
计算机软件
Windows快捷键
Ctrl + X | 剪切 |
---|---|
Ctrl + Z | 撤销 |
Windows + R | 打开运行窗口,输入cmd打开命令行窗口 |
Windows + E | 打开我的电脑 |
Ctrl + Shift + ESC | 打开任务管理器 |
Windows + P | 打开分屏投影 |
Windows DOS命令
打开命令行窗口的方式
- 从开始 + Windows系统+命令提示符 点击打开
- Windows + R 打开运行窗口,输入cmd打开命令行窗口
- 在任意文件夹下,按住shift键+鼠标右击,选择 在此处打开powershell窗口
- 资源管理器的地址栏前面加上 cmd 文件路径,就能打开该路径下的cmd窗口
以管理员方式运行:右击命令提示符选择以管理员方式运行,便能获得root最高运行权限。
常用的DOS命令
#盘符切换 C: D: E:即可
C:
#查看当前目录下的所有文件
dir
#切换目录 change directory
cd
#切换到不同盘符下的目录 /d才能不同盘符切换
cd /d E:nomalSoft
#清理屏幕 clear screen
cls
#退出终端
exit
#查看ip地址
ipconfig
#dos命令打开软件应用
#calc 打开计算器 mspaint 打开画图 notepad 打开记事本
#ping命令 测试网络是否正常连接该网址主机
ping www.google.com
#文件操作
#创建文件夹 make directory
md test
#删除文件夹 remove dirctory
rd test
#创建文件 cd> 文件名
cd>demo.text
#删除文件 del
del demo.text
根据电脑的连接,如目前连无线网则ip在无线适配器WLAN上:
计算机语言
- 第一代机器语言——二进制
- 第二代汇编语言——逆向工程时使用
- 第三代高级语言——面向过程和面向对象
摩尔定律是英特尔创始人之一戈登·摩尔的经验之谈,其核心内容为:集成电路上可以容纳的晶体管数目在大约每经过18个月便会增加一倍。换言之,处理器的性能每隔两年翻一倍。
Java环境的搭建
Java构建程序需要用到的平台,系统和工具。
什么是JDK,JRE,JVM?
JDK目录介绍:
JDK环境变量配置
JDK的环境变量配置时只需要配置%JAVA_HOME%\bin
即可,不需要再对jre\bin
进行配置的原因是JDK包含了JRE,我们可以看到JDK\bin
目录下已经包含了JRE的目录了,因此只要配置一个环境变量就行了。
手动编译Java文件
#首先进入到要编译的java文件所在文件夹目录下
cmd D:\md_note\kuangstudy
#编译java文件,注意要带java后缀
javac Application.java
#编译后会生成Application.class 字节码文件
#java class文件名 ,执行java代码。运行时直接运行java文件名即可,不可以带Application.class后缀,否则会报找不到或无法加载主类
java Application
#注意如果是Windows平台默认是GBK编码,所有编译时要指定编码格式为utf8需要如下操作
#编译:
javac -encoding utf8 Test.java
#执行:
java -Dfile.encoding=utf8 Test
注意:java文件如果有包名路径的话则编译后的class文件也要在对应的包名下,否则会执行报错。
Java程序运行机制
编译型——直接编译成机器码,相当于把一本书从中文翻译成英文
解释型——一行一行解释成机器码执行,相当于把一本中文书让一个翻译官一行一行翻译成英文给老外听
Java基础
数据类型
8大数据类型(byte,short,int,long,float,double,char,boolean)
位与字节的关系
代码示例
public class Test {
public static void main(String[] args) {
//整数有不同进制,二进制:0b,十进制 ,八进制:0,十六进制:0x
int a = 10;
int b = 0b10;
int c = 010;
int d = 0x10;
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
System.out.println("-------------------------------------------------------------");
//浮点数 ,针对金钱的计算一定要避免使用浮点数进行比较,因为浮点数存储位数有限,离散,有误差,会舍入误差,值接近但不等于
float e = 0.1f;
double f = 1.0 / 10;
System.out.println(e == f);//false float与double值有效位不一样,当一个浮点数做运算时如果指定类型则为了精度默认为double类型
float g = 1011010101001f;
float h = g + 1;
System.out.println(g == h);//true 浮点数数值过大会丢失精度
System.out.println("-------------------------------------------------------------");
//字符 ,所有的字符本质上还是数字,Unicode编码表是字符与数字的对应关系
//如 97=a ,65=A,表示0-65536的数,2的16次方=65536 一个字节8位,字符=2个字节=16位
char i = 'A';
char j ='\u0061';//这里是十六进制数,对应十进制是65
char k = (char)97;
int l = (int)i;
System.out.println(i);
System.out.println(j);
System.out.println(k);
System.out.println(l);
//转义字符 \t 制表符 \n换行符
System.out.println("with\tme");
System.out.println("with\nme");
}
}
/**输出:
* 10
* 2
* 8
* 16
* -------------------------------------------------------------
* false
* true
* -------------------------------------------------------------
* A
* a
* a
* 65
* with me
* with
* me
*/
类型转换
- 强制类型转换——类型从高转低,如long转int
- 自动类型转换——类型从低转高,如int转long
类型转换注意点:
- 不能对布尔值进行转换
- 不能把对象类型转换为不相干的类型,如int不能转String
- 类型从高转低进行强转时可能会出现内存溢出或者精度问题,如int转byte,double转long
代码示例
public class Test {
public static void main(String[] args) {
//JDK7新特性,数字之间可以用下划线分割,方便程序员读数。
int num = 1_0000_0000;
System.out.println(num);//100000000
int year = 500;
System.out.println(num * year);//-1539607552 int类型内存溢出
//较大数值计算时要注意内存溢出问题,运算前先把一个乘数值转为较大类型如long,
// 否则即使结果用long类型来作为接受结果也没用,因为会进行先int类型计算再转型为long,
//这时候已经失去精度或者内存溢出了
System.out.println((long) num * year);//50000000000
/**
* 输出:
* 100000000
* -1539607552
* 50000000000
*/
}
}
常量:初始化后不能再改变的值,被final
修饰。
静态常量:被final static
修饰。
常量命名:大写字母加下划线:MAX_MEMORY
运算示例
public class Test2 {
/**
* 自增运算示例
*
* @param args
*/
public static void main(String[] args) {
int a = 1;
int b = a++;//执行顺序:先给b赋值,再自增
int c = ++a;//执行顺序:先自增,再给c赋值
System.out.println(a);//3
System.out.println(b);//1
System.out.println(c);//3
//幂运算 借助工具类Math
double v = Math.pow(2, 3);//8.0 2^3次方
System.out.println(v);
System.out.println("------------------------------------------");
//测试短路
int i = 10;
boolean j = (i > 15) && (i++ > 15);
System.out.println(i);//10,输出是10表示短路了,没有进行后面的i++运算
System.out.println(j);//false
System.out.println("---------------------位运算符---------------------");
/**
* 位运算符
* A:1010 1100
* B:1001 0110
*A&B = 1000 0100
*A|B = 1011 1110
*A^B = 0011 1010 A与B同时为0或1则为0,A与B值不同则为1
*~A = 0101 0011
*
* << 相当于*2 右补齐0
* >> 相当于/2 左补齐0
*/
int k = 2 * 8;
int l = 2 << 3;//位运行效率高
double v1 = Math.pow(2, 16);
double v2 = 2 << 15;//2^16次方相当于左移15位
System.out.println(k);//16
System.out.println(l);//16
System.out.println(v1);//65536.0
System.out.println(v2);//65536.0
}
}
Javadoc生成文档
第一种方法是直接打开java文件所在的类,执行下面这个语句
#-encoding是java代码编码,-charset是对生成文档所用的编码
javadoc -encoding utf-8 -charset utf-8 Test.java
第二种是使用idea帮我们生成,选择tool——generate JavaDoc
用户交互类——Scanner
代码示例
public class ScannerTest {
public static void main(String[] args) {
//从键盘接收数据
Scanner scanner = new Scanner(System.in);
// while (scanner.hasNext()){
// System.out.println("输出:"+scanner.next());
// }
//判断是否还有输入:代码会在这个位置等待输入
if (scanner.hasNextLine()){
System.out.println("输出:"+scanner.nextLine());
}
//IO流只要有打开就一定要关闭
scanner.close();
}
}
Switch语句
代码示例
public class SwitchTest {
public static void main(String[] args) {
//注意case穿透问题,如果从上面匹配到mike后没有break语句,则case还会继续往下执行,把 default也打印出来,
//所以一般要注意加break语句
//JDK7新特性 switch语句可以使用String来判断,我们通过查看反编译文件可以发现本质上是通过字符串的hashCode()值(是个int值)
// 来进行判断,而枚举类也能用于switch语句是因为其调用的是枚举类的ordinal()方法,也就是枚举的序列号来判断
String name = "mike";
switch (name) {
case "tom":
System.out.println("tom");
break;
case "mike":
System.out.println("mike");
break;
default:
System.out.println("no one");
}
}
}
想要查看反编译后的class文件对应的值,直接打开class文件是看不懂的,我们可以通过将该class文件拷贝到src源码包下的位置,通过idea来打开,就能看到反编译后的代码了。
switch反编译结果如下:
方法
值传递和引用传递,Java是值传递。
方法重载
命令行传参
参考手动编译java文件一节,注意编译后要执行的class文件需要带包名执行,否则找不到class文件。命令行传参其实就是在执行语句后面加入要传的参数即可。也可以直接使用idea的program arguments进行传参。
可变参数
代码示例
public class Test3 {
public static void main(String[] args) {
//可变参数使用时也可以不穿参数,本质上就是个数组,因此我们在传参时可以直接传个数组进去。
Test3.printAll("a", "little", "guy");
Test3.printAll(3, new String[]{"I", "am ", "Ironman"});
}
public static void printAll(int i, String... str) {
System.out.println(i);
System.out.println(Arrays.toString(str));
}
public static void printAll(String... str) {
System.out.println(Arrays.toString(str));
}
/**
* [a, little, guy]
* 3
* [I, am , Ironman]
*/
}
递归
利用递归可以用简单的程序解决复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似但规模较小的问题。递归的能力在于用有限的语句来定义对象的无线集合。
递归要注意的便是递归不能太深,否则会栈溢出或者计算太久空间浪费。
递归结构包含两个部分
- 递归头:什么时候不调用自身方法
- 递归体:什么时候调用自身方法
递归案例
- 输入一个地区名获得其下面全部所有的区县。如输入深圳市或者浙江省获取其下面所有区县。
- 数学阶乘
代码示例
public class Test5 {
public static void main(String[] args) throws Exception {
int result = Test5.factorial(6);
System.out.println(result);//720
}
public static int factorial(int n) throws Exception {
if (n <= 0) {
throw new Exception("n is illegal");
}
if (n == 1) {
return 1;
}
return n * factorial(n - 1);
}
}
数组
代码示例
冒泡排序
public class Test6 {
public static void main(String[] args) {
int[] arr = {1, 4, 5, 333, 321, 65, 65, 332, 12, 44, 56, 888};
int[] sortArr = bubbleSort(arr);
System.out.println(Arrays.toString(sortArr));
//[1, 4, 5, 12, 44, 56, 65, 65, 321, 332, 333, 888]
}
/**
* 冒泡排序
* @param arr
* @return
*/
public static int[] bubbleSort(int[] arr) {
int temp;
for (int i = 0; i < arr.length - 1; i++) {
boolean flag = false;
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = true;
}
}
if (!flag) {
break;
}
}
return arr;
}
}
稀疏数组
稀疏数组的使用前提是原始数组中大部分的元素是相同的或者是默认值如0,这样我们对原始数组进行有效的压缩成稀疏数组来减少空间的占用。稀疏数组的第一行记录原始数组长度和宽度,以及一共有多少个值。第二行到最后一行记录每个值所在原始数组的坐标及值。
面向对象
本质:以类的方式组织代码,以对象的形式封装数据。
抽象、封装、继承、多态
对象封装的标准:属性私有,对外提供getter/setter
构造器
子类和父类构造器问题:当父类只有有参的构造器,没有无参构造器时,子类也必须是有参的构造器,并显示调用父类的有参构造器,否则报错,毕竟是继承关系,父类是要先被创建出来的,如果父类的有参构造器没有被调用则无法构建出父类对象。
示例:
public class Son extends Father{
public Son(Integer id) {
//显示调用父类构造器
super(id);
}
}
public class Father {
private Integer id;
public Father(Integer id) {
this.id = id;
}
}
初始化顺序
代码示例
public class Test7 {
public static void main(String[] args) {
A a1 = new A();
System.out.println("-----------------------");
A a2 = new A();
/**
* 静态代码块
* 匿名代码块
* 构造器
* -----------------------
* 匿名代码块
* 构造器
*/
}
}
public class A {
//只在第一次初始化时执行,且只执行一次
static {
System.out.println("静态代码块");
}
//每次创建对象时都会执行一次,可以在匿名代码块中赋初值,在构造器前执行
{
System.out.println("匿名代码块");
}
//每次创建对象时都会执行一次
public A() {
System.out.println("构造器");
}
}
抽象类和接口
抽象类有构造方法,接口没有构造方法。
内部类
- 成员内部类——在外部类里面定义的内部类
- 静态内部类——被static修饰的内部类
- 局部内部类——定义在方法里面的类
- 匿名内部类——直接实现接口或抽象类重写方法的类
内部类可以调用外部类的私有属性和私有方法。
一个Java文件中只能有一个public class
类,但是可以有多个class类定义。
参考学习HashMap中的内部类
异常
自定义异常继承Exception。
扩展
1、idea创建对象时要快速获得对象对应的变量名有两个方法如下
Test2 test2 = new Test2();
// new Test2().var 加上.var
//在new Test2()这行使用alt + enter
2、idea快速生成给定数字的for循环的快捷方式
100.for 即可,还可以选择是递增还是递减
3、idea快捷键ctrl+alt+t 不生效,无法快捷生成
try catch
这个是电脑上的QQ或TIM的热键导致的,而且设置里还没法更改,需要先在设置的热键中给某个功能加上ctrl+alt+t,让其生效了再删除掉这个热键,这样就不会出现这个问题了。真恶心。
[参考](求高手回答,如何干掉腾讯QQ的全局热键CTRL+ALT+T? - aNightCat的回答 - 知乎 https://www.zhihu.com/question/271586548/answer/374660485 )
4、大数据领域——Hadoop——Java写的,所以Java在大数据领域使用比较广泛。
疑问
JDK环境或者其他我们安装的例如Mysql在linux中要如何卸载才能算完全卸载好了?删除安装目录文件,删除环境变量配置?