Java基础
JDK (Java Development Kit) Java开发工具包
JRE (Java Runtime Environment) Java运行环境
JVM (Java Virtual Machine) Java虚拟机
\[\begin{array}{l} JDK &= JRE &+ Java开发工具[java, javac, javadoc, javap...] \\ &= JVM + Java核心类库 &+ Java开发工具[java, javac, javadoc, javap...] \end{array} \]\[\require{AMDcd} \begin{CD} Test.java @>javac>> Test.class @>java>> \rm{JVM\,\,for\,\,Windows}\\ \end{CD} \]javac Hello.java
java Hello
一个源文件中最多只能有一个public类,其他类的个数不限;main方法写在非public类,入口也跟着变
编译后,每个类都对应一个class文件
Tab 整体向右边缩进
Shift + Tab 整体向左边缩进
DOS命令 | Disk Operating System |
---|---|
dir | |
D: | |
cd \ | |
cd .. | |
cd d:\ | |
cd d:\program | |
help cd | |
tree d:\program | |
cls | |
exit | |
md [创建目录] | |
rd [删除目录] | |
copy | |
move | |
echo | |
type | |
del |
[有符号] | $-2^{n-1} $ | \(-(2^{n-1}-1)\) | $-1 $ | \(-0\) | \(+0\) | $+1 $ | $2^{n-1}-1 $ |
---|---|---|---|---|---|---|---|
原码 | \(1,1111111\) | \(1,0000001\) | \(1,0000000\) | \(0,0000000\) | \(0,0000001\) | \(0,1111111\) | |
反码 | \(1,0000000\) | \(1,1111110\) | \(1,1111111\) | \(0,0000000\) | \(0,0000001\) | \(0,1111111\) | |
补码 | \(\color{lime}1,0000000\) 0x8000[16b] | \(1,0000001\) 0x8001 | \(1,1111111\) 0xFFFF | \(\color{red}0,0000000\) 0x0000 | \(\color{red}0,0000000\) 0x0000 | \(0,0000001\) 0x0001 | \(0,1111111\) 0x7FFF |
移码 | \(0,0000000\) | \(0,0000001\) | \(0,1111111\) | \(1,0000000\) | \(1,0000000\) | \(1,0000001\) | \(1,1111111\) |
Java的整型常量默认为 int 型,声明 long 型常量须后加 'l' 或 'L'
Java的浮点型常量默认为 double 型,声明 float 型常量须后加 'f' 或 'F'
API (Application Programming Interface) 应用程序编程接口
字符类型 char 占两个字节
字符编码表 | ||
---|---|---|
ASCII | 一个字节 | \(2^8\) 只用128个 |
Unicode | 两个字节 | \(2^{16}\) 65536 |
UTF-8 | 字母1个字节,汉字3个字节 | |
GBK | 字母1个字节,汉字2个字节 | |
GB2312 | gb2312 < gbk | |
BIG5 | 繁体中文 台湾、香港 |
Java里布尔类型 boolean 只能是true和false,不能用数值代替
自动类型转换:
\[\require{AMDcd} \begin{CD} @. char @>>> int @>>> long @>>> float @>>> double \\ byte @>>> short @>>> int @>>> long @>>> float @>>> double\\ \end{CD} \]强制类型转换
(int)
\[a\,\, \% \,\,b \,=\, a - a \,/ \,b\, *\, b \\ a为小数时, \,\,a \,\, \% \,\, b \,=\, a - (int)a \,/\, b \,*\, b \\ \]x = i++; (temp = i; i = i + 1; x = temp)
x = ++i; (i = i + 1; temp = i; i = temp)
逻辑运算符 | |
---|---|
短路与 | && |
短路或 | || |
取反 | ! |
逻辑与 | & |
逻辑或 | | |
逻辑异或 | ^ |
结合方向 | 运算符优先级(从上至下) |
---|---|
. () {} ; , | |
\(\longleftarrow\) | ++ -- ~ !(data type) |
\(\longrightarrow\) | + / % |
\(\longrightarrow\) | + - |
\(\longrightarrow\) | << >> >>> 位移 |
\(\longrightarrow\) | < > <= >= instanceof |
\(\longrightarrow\) | == != |
\(\longrightarrow\) | & |
\(\longrightarrow\) | ^ |
\(\longrightarrow\) | | |
\(\longrightarrow\) | && |
\(\longrightarrow\) | || |
\(\longrightarrow\) | ? : |
\(\longleftarrow\) | = *= /= %= |
+= -= <<= >>= | |
>>>= &= ^= |= |
进制转换:
\[\begin{align} &n位r进制整数\qquad转十进制\\ &X=K_{n-1}K_{n-2}K_{n-3}\cdots K_2K_1K_0\\[2ex] \implies&Y=K_{n-1}\times r^{n-1}+K_{n-2}\times r^{n-2}+K_{n-3}\times r^{n-3}\cdots+K_2\times r^2+K_1\times r^1+K_0\times r^0 \tag{1}\\[2ex] \implies&Y=(((K_{n-1}\times r+K_{n-2})\times r+K_{n-3})\times r+\cdots K_1)\times r+K_0 \tag{2}\\ \end{align} \](1)式和(2)式可推导出两种转十进制的写法:
二进制 | 八进制 | 十进制 | 十六进制 |
---|---|---|---|
0 | 0 | 0 | 0 |
1 | 1 | 1 | 1 |
10 | 2 | 2 | 2 |
11 | 3 | 3 | 3 |
100 | 4 | 4 | 4 |
101 | 5 | 5 | 5 |
110 | 6 | 6 | 6 |
111 | 7 | 7 | 7 |
1000 | 10 | 8 | 8 |
1001 | 11 | 9 | 9 |
1010 | 12 | 10 | A |
1011 | 13 | 11 | B |
1100 | 14 | 12 | C |
1101 | 15 | 13 | D |
1110 | 16 | 14 | E |
1111 | 17 | 15 | F |
20 | 16 | 10 |
int n1 = 0b1010;
int n2 = 1010;
int n3 = 01010;
int n4 = 0x1010;
输出默认十进制格式
Java中负的十六进制怎么直接写?
查:10进制数有正负之分,比如12表示正12,而-12表示负 12;但8进制和16进制只能用达无符号的正整数,如果你在代码中里:-078,或者写:-0xF2,编译器并不把它当成一个负数。
位运算:应用进制转换
\[\begin{align} &r进制\\ &K_nK_{n-1}\cdots K_2K_1K_0.K_{-1}K_{-2}\cdots K_{-m}\\ &=K_n \times r^n+K_{n-1}\times r^{n-1}+\cdots+K_2\times r^2+K_1\times r^1+K_0\times r^0+K_{-1}\times r^{-1}+K_{-2}\times r^{-2}+\cdots+K_{-m}\times r^{-m}\\ \end{align} \]\[通过改变各个数码位和小数点的相对位置,从而改变各数码位的位权。移位运算实现乘法、除法。\\ 小数点右移(后移)n位\iff \times r^n \iff 数左移\\ 小数点左移(前移)n位\iff \div r^n \iff 数右移\\ \]计算机内部运算的是补码(统一正负数)
Integer.toHexString() 可以看到16进制补码
Java没有无符号数,换言之,Java中的数都是有符号的
位运算符 | |
---|---|
& | 按位与 |
| | 按位或 |
^ | 按位异或 |
~ | 按位取反 |
>> | 算术右移(符号位不变,高位补符号位) |
<< | 算术左移(符号位不变,低位补0) |
>>> | 逻辑右移(高位补0) |
无逻辑左移 |
switch case语句没有break会穿透向下执行
Math.random() [0,1)
Math.random() * 100 [0,100)
(int)(Math.random() * 100) 0,1,2,...,98,99
(int)(Math.random() * 100) + 1
import java.util.Scanner;
3.1声明和初始化
01 每行声明一个变量
例外:for语句中第一部分通常用于计数器的初始化,可以接收多个变量声明
02 局部变量被声明在接近它们首次使用的行
局部变量要么在声明时初始化,要么声明后立即被初始化,没有必要设置为无效的null值
03 禁止C风格的数组声明
数组翻转:
偶数个:
\[\underbrace{[1]\quad [2]\quad \cdots \quad [k-1] \quad [k]}_{k个}\quad \underbrace{[k+1]\quad \cdots \quad[2k-1] \quad[2k]}_{k个} \tag{k=1,\,\,2,\,\,...} \\[3ex] \begin{array}{l} [1] \leftrightarrow [2k]\\ [2] \leftrightarrow [2k-1] \\ [i] \leftrightarrow [2k-i+1] \iff [L-i+1] \\ [k] \leftrightarrow [k+1] \\ \end{array} \\[2ex] \]L = 2k; //Length
for i = 1 to k do
a[i]<->a[L-i+1]
奇数个:
\[\underbrace{[1]\quad [2]\quad \cdots \quad [k-1] }_{k-1个}\quad [k]\quad \underbrace{ [k+1]\quad\cdots \quad[2k-2] \quad[2k-1]}_{k-1个} \tag{k=1,\,\,2,\,\,...} \\[3ex] \begin{array}{l} [1] \leftrightarrow [2k-1]\\ [2] \leftrightarrow [2k-2] \\ [i] \leftrightarrow [2k-i] \iff [L-i+1] \\ [k-1] \leftrightarrow [k+1] \\ [k] \leftrightarrow [k] \\ \end{array} \\[2ex] \]L = 2k - 1; //Length
for i = 1 to k do
a[i]<->a[L-i+1]
下标为0开始,偶数个
\[\underbrace{[0]\quad [1]\quad [2]\quad \cdots \quad [k-1]}_{k个}\quad \underbrace{[k]\quad [k+1]\quad \cdots \quad[2k-1]}_{k个} \tag{k=1,\,\,2,\,\,...} \\[3ex] \begin{array}{l} [0] \leftrightarrow [2k-1]\\ [1] \leftrightarrow [2k-2] \\ [i] \leftrightarrow [2k-1-i] \iff [L-1-i]\\ [k-1] \leftrightarrow [k] \\ \end{array} \\[2ex] \]L = 2k;
for i = 0 to k-1 do
a[i]<->a[L-1-i]
冒泡排序:
for i = 1 to n-1 do
for j = 0 to n-1-i do
if a[j] > a[j+1]
a[j] <-> a[j+1]
面向对象编程(OOP)基础
创建一个对象 / 实例化一个对象 / 把类实例化 / ...
类是数据类型(抽象的、概念的),对象是类的一个实例(具体的、实际的)
成员变量 / 属性 / 字段 / field 初始化不赋值有默认值
Java创建对象的流程
1.方法区加载类信息(属性和方法信息,只会加载一次)
2.堆中分配空间,属性默认初始化
3.地址赋值给对象名
先创建对象,再调用方法
方法调用机制
1.main栈
2.调用方法,开辟新的栈空间
3.返回
有返回类型,必须有return sth;
void 可以没有return ,或者只有 return ;
方法不能嵌套定义
同一个类中的方法调用:直接调用即可【自己公司里的小明,直接叫就行了(小明在本公司唯一),别的公司的小明要带上公司名再叫】
跨类中的方法A类调用B类方法:需要通过对象名调用,比如 对象名.方法名(参数) 访问修饰符?
成员方法传参机制:基本数据类型值传递,引用数据类型地址传递
递归:
T t1 = new T();
int res = t1.factorial(5);
class T {
public int factorial(int n) {
if (n == 1) {
return 1;
} else {
return factorial(n - 1) * n;
}
}
public int fibonacci(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
}
方法重载 Overload
把握方法重载的关键:1.方法名相同 2. 形参列表的数据类型或个数或顺序不同,参数名无要求 3.返回类型无要求
《Java核心技术卷一》
Java允许重载任何方法,而不只是构造器方法
完整地描述一个方法,需要指定方法名以及参数类型,这叫做方法的签名(signature)
查找匹配的过程被称为重载解析(overloading resolution)
返回类型不是方法签名的一部分
可变参数 Variable parameter
同一个类中,多个同名,同功能,但参数个数不同的方法,封装为一个方法(方法重载)
class T {
public void f1(int... nums) {
可变参数细节123456
}
}
\[变量
\begin{cases}
全局变量, & \text{属性/成员变量} \\
局部变量, & \text{成员方法中定义的变量} \\
\end{cases}
\]\[变量作用域
\begin{cases}
全局变量——整个类 \\
局部变量——定义代码块 \\
\end{cases}
\]\[变量初始化
\begin{cases}
全局变量——可以不赋值,直接使用,因为有默认值 \\
局部变量——必须赋值初始化才能使用,因为没有默认值 \\
\end{cases}
\]总结:定义的变量只能在离自己最近的外层大括号内使用(作用域)
属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。
局部变量生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而死亡。即在一次方法调用过程中。
构造器 constructor
1)方法名和类名相同
2)没有返回值
3)在创建对象时,系统会自动的调用该类的构造器完成对对象的初始化
构造器不是创建对象,而是初始化对象
new的时候创建对象,对象空间已经有了,构造器再初始化对象
构造器重载
构造器不能手动去调用,只能系统调用
\[\require{AMDcd} \begin{CD} Constructor01.java @>javac>> 找到Dog.class @>javap>> \rm{程序员可以看的类}\\ \end{CD} \]如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫默认构造器),比如 Dog(){},使用 javap 指令反编译可以看到
一旦定义了自己的构造器,默认的构造器就被覆盖了,不能再使用默认的无参构造器,除非显式的定义一下,即 Dog(){} (后面继承会用到)
javac Constructor01.java
javap Dog.class (javap Dog)
Java创建对象的流程(更新)
1.方法区加载类信息(属性和方法信息,只会加载一次)
2.堆中分配空间
3.对象初始化 ①属性默认初始化 ②属性显式初始化 ③构造器初始化
4.对象在堆中的地址赋值给对象名
《Java核心技术卷一》
初始化数据字段的具体步骤
1.若调用别的构造器,先执行 (this调用)
2.数据字段初始化为默认值
3.按照在类中的声明顺序,执行字段初始化方法和初始化块
4.执行构造器
Java虚拟机会给每个对象分配this,代表当前对象(this隐藏在对象里)
当前对象就是当你创建好这个对象后,谁在调用这个构造器,这个this就是那个对象
前面讲过,当我们执行到构造器的时候,这个对象其实已经有了,这个this指的就是你new出来的这个对象
this小结:简单的说,哪个对象调用,this就代表哪个对象
在构造器中访问另一个构造器,使用this(参数列表)且必须是第一条语句(原因继承讲)
任何一个类,都可以有main方法
匿名对象 没有名字,用完后就会被销毁
面向对象编程(中级)
IDEA快捷键(11个) | Settings\Keymap | 搜索 | |
---|---|---|---|
删除当前行 | Delete Line | Ctrl + D | delete |
复制当前行 | Duplicate Line or Selection | Ctrl + Alt + 向下箭头 | duplicate |
补全代码 | Cyclic Expand Word | Alt + / | |
添加注释/取消注释 | Comment with Line Comment | Ctrl + / | |
快速格式化代码 | Reformat Code | Ctrl + Alt + L | format |
快速运行程序 | Run | Alt + R | run |
导入该行需要的类? | 打开auto ... 然后Alt + Enter | ? | ? |
生成构造方法 | Generate... | Alt + Insert | |
查看一个类的层级关系 | Type Hierarchy | Ctrl + H | 选定类 |
定位到方法 | Go to Declaration or Usages | Ctrl + B | 选定方法 |
自动分配变量名 | new xxx().var | .var | ? |
运行当前窗口 | Ctrl + Shift + F10 |
包的本质:保存类文件的文件夹(目录)
常用的包:java.lang.* java.util.*
lang包是基本包,默认引入
包含 Math、Object、String、System、包裹类型(Boolean、Byte、Character、Double、Float、Integer)、Enum
java.util.* 工具包 Scanner和Arrays都在这里
java.net.* 网络包
java.awt.* 界面开发
import java.util.Arrays;
Arrays.sort();
package 的作用是声明当前类所在的包
封装
继承
父类 / 基类 / 超类
子类 / 派生类
子类继承了父类所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问
父类中增加或去掉一个方法或属性,所有子类都会收到影响子类必须调用父类的构造器,完成父类的初始化
当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则编译不通过【子类的构造器隐藏了super() 父类的无参构造器】
父类的无参构造器如果被覆盖了,子类得用super(参数列表)super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
父类构造器的调用不限于直接父类,将一直往上追溯到Object类(顶级父类)
继承的本质:
多态
类定义:
package 包名;
class 类名 {
属性/成员变量;
构造器;
成员方法;
}
标签:初始化,Java,构造,times,quad,JavaSE,2k
From: https://www.cnblogs.com/KnowledgeMask/p/16910187.html