Java基础

Hello World

编译运行

1
2
3
java源文件 -> class字节码文件 -> java运行class文件
javac java文件 # 输出class字节码文件
java class文件

Hello World

1
2
3
4
5
public class HelloWord {  // 与文件名一致
public static void main(String[] args) { // 主函数
System.out.println("Hello World");
}
}

主函数

1
2
3
public static void main(String[] args){

}

输入输出

1
2
3
4
5
6
7
8
9
10
11
12
13
输入
import java.util.Scanner

Scanner sc = new Scanner(System.in);

int q = sc.nextInt();
String c = sc.next();

输出
System.out.println(值); // 换行
sout // 匹配

System.out.print(值); // 不换行

注释

1
2
3
4
5
6
7
8
9
10
11
public class HelloWorld {
/* 这是第一个Java程序
* 它将输出 Hello World
* 这是一个多行注释的示例
*/
public static void main(String[] args){
// 这是单行注释的示例
/* 这个也是单行注释的示例 */
System.out.println("Hello World");
}
}

数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
byte
byte 数据类型是8位、有符号的,以二进制补码表示的整数
最小值,-128(-2^7),最大值 1272^7-1),默认值 0
byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
例子:byte a = 100byte b = -50
short
short 数据类型是 16 位、有符号的以二进制补码表示的整数
-32768(-2^15),327672^15 - 1),0
一个short变量是int型变量所占空间的二分之一
int
int 32位,……
-2,147,483,648(-2^31),2,147,483,6472^31 - 1),0
long
64
默认值 0L,一般不分大小写,最好大写,区分 小写l
long a = 100000L
float
float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;
float 在储存大型浮点数组的时候可节省内存空间;
默认值是 0.0f
浮点数不能用来表示精确的值,如货币;
例子:float f1 = 234.5f
double
double 数据类型是双精度、64 位、符合 IEEE 754 标准的浮点数;
浮点数的默认类型为 double 类型;
double类型同样不能表示精确的值,如货币;
默认值是 0.0d

例子:
double d1 = 7D ;
double d2 = 7.;
double d3 = 8.0;
double d4 = 8.D;
double d5 = 12.9867;
7 是一个 int 字面量,而 7D7.8.0double 字面量。

boolean
boolean数据类型表示一位的信息;
只有两个取值:truefalse
这种类型只作为一种标志来记录 true/false 情况;
默认值是 false
例子:boolean one = true
char
char 类型是一个单一的 16 位 Unicode 字符;
最小值是 \u0000(十进制等效值为 0);
最大值是 \uffff(即为 65535);
char 数据类型可以储存任何字符;
例子:char letter = 'A';。

类型转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 自动类型转换(运算)
整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。
转换从低级到高级。
低 ---------------------------------------> 高
byte,short,char—> int —> long—> float —> double
1. 不能对boolean类型进行类型转换。
2. 不能把对象类型转换成不相关类的对象。
3. 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
4. 转换过程中可能导致溢出或损失精度,例如:
5. 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,

// 强制类型转换
1. 条件是转换的数据类型必须是兼容的。
2. 格式:(type)value type是要强制类型转换后的数据类型

// 隐式类型转换(不同类型赋值)
1. 整数的默认类型是 int。
2. 小数默认是 double 类型浮点型,在定义 float 类型时必须在数字后面跟上 F 或者 f。

条件控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// if
if(条件表达式){
....
}else if(条件表达式){
....
}...
else{
....
}

// switch (3种格式)
switch(条件表达式){
case 1:
....;
break;
case 2:
....;
break;
....
default:
....;
}

switch(条件表达式){
case 1 -> ....;
case 2 -> ....;
....
default -> ....;
}

switch(条件表达式){
case 1 -> {
....;
....;
}
case 2 -> {
....;
....;
}
....
default -> {
....;
....;
}
}

循环控制

1
2
3
4
5
6
7
8
9
10
11
for( ;条件表达式; ){
.....;
}

while(条件表达式){
....;
}

do{
....;
}while(条件表达式);

数组

定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
静态定义
int[] array = new int[]{1,2,3};
int[] array = {1,2,3}; // 简写
int array[] = {1,2,3}; // 一样

String[] array = new String[]{"zhangsan""lisi","wangwu"};
String[] array = {"zhangsan""lisi","wangwu"}

动态定义
int[] array = new int[50];
array[0] = 1;
array[1] = 2;
....
数组默认初始化值
整型 0
浮点型 0.0
字符型 '/u0000' 空格
布尔型 false
引用 null

二维数组
int[][] array = new int[][]{{1,2},{3,4}};
int[][] array = {{1,2},{3,4}}; // 简写

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int[] array = {1,2,3};
array 表示数组地址
array[0] 第一个元素 1
array[1] 第二个元素 2
array[2] 第三个元素 3

System.out.println(array); // [I@776ec8df
[ 固定的格式
I 数据类型
@ 间隔符
776ec8df 16进制地址


for(i=0;i<array.length;i++){
System.out.println(array[i]);
}

随机数

1
2
Random r = new Random();
int i = r.nextInt(100)+1; // 1-100 随机数

方法

定义

1
2
3
4
5
6
7
public static void 方法名(数据类型 形参){
....
}

public static void fun(){
....
}

调用

1
2
3
方法名(实参);

fun();

重载

1
2
3
4
5
6
7
8
9
10
// 相同方法名,形参不同
public static int num(int a){
return a;
}
public static float num(int a,float b){
return c = a + b;
}
public static void num(int a,float b,char c){
return ;
}

String

一旦定义,无法更改(内存中),直接赋值 = 指向拼接出新的字符串

值相同的 String 指向同一个区域(仅限直接赋值)

1
2
3
4
5
6
7
8
9
10
String name1 = "qweq";
直接赋值 存储到串池,串池是堆中的一个特殊区域
String name2 = new String("asb");
new String 存储到堆中
String name3 = new String();
空参构造
char[] chr4 = {'a','b','c'};
常见类型 存储在堆中
String chr5 = new String(chr4);
把 chr4 拼接,在堆中新开辟一个区域存储

字符串比较

equals 字符串值比较

equalsIgnoreCase 字符串值比较 忽略大小写

1
2
3
4
5
6
String s1 = new String("abc");  // 堆
String s1 = "abc"; // 串池
sout(s1 == s2); // false

boolean r = s1.equals(s2);
sout(r); // ture

StringBuilder

可以看成一个容器,创建之后里面的内容是可以变的

StringBuilder(可以空参构造,也可以带有参数)

成员方法

apppen 添加数据

reverse 反转容器内的内容

length 返回长度(字符出现个数)

toString 把StringBuilder转换为String

1
2
3
4
5
6
7
8
9
10
11
StringBuilder sb = new StringBuilder();
sb.append("a");
sb.append("n");
sb.append("c");
sout(sb); // abc
sout(sb.reverse()); //cba
sout(sb.length()); // 3
String bs = sb.toString(); 这样才能把值赋给 String 类型的变量

链式方法
int i = new StringBuilder("abc").append("123").length();

StingJoiner

例如,将数组转换成字符串时,简略代码

1
import java.util.StringJoiner;

StingJoiner(间隔符号)

StingJoiner(间隔符号,开始符号,结束符号)

成员方法

add

length

toString

1
2
3
4
5
6
7
int[] arr = {1,2,3};
StringJoiner sj = new StringJoiner(", ","[","]");
for (int i = 0; i < arr.length; i++){
sj.add(arr[i]+""); // + "" 是为了转换为字符串
}
System.out.println(sj);
System.out.println(sj.toString()); // 输出一样

集合

ArrayList

1
import java.util.ArrayList;

ArrayList

方法

add

remove(元素)

remove(索引)

set(索引,值) 修改

get(索引) 获取索引元素

size (集合长度)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// ArrayList<String> list = new ArrayList<String>();
ArrayList<String> list = new ArrayList<>(); // JDK7之后

ArrayList<String> list = new ArrayList<>(); // JDK7之后
list.add("abc");
list.add("bbb");
list.add("ccc");

System.out.println(list);

list.remove("abc");
System.out.println(list);

list.remove(0);
System.out.println(list);

list.set(0,"123");
System.out.println(list);

String a = list.get(0);
System.out.println(a);

System.out.println(list.size());


[abc, bbb, ccc]
[bbb, ccc] // 删除了abc,索引改变 bbb <- 0 ccc <-1
[ccc] // 索引只有 0
[123]
123
1

标号

1
2
3
4
5
6
7
8
loop: while (ture){
while (ture){
while (ture)
break loop;
}
}

推出最外层循环,标号名字自定义

static

定义给公用的方法 成员变量

静态方法中,只能访问静态

非静态可以访问所有

静态中没有this关键字(非静态中默认有,系统给的)

继承

构造方法无法继承

虚方法:非private 非static 非final

虚方法继承给子类

1
2
3
4
5
6
7
8
9
10
11
12
class Fu {
String name = "Fu";
}
class Zi extends Fu {
String name = "Zi";
public void show() {
String name = "show";
System.out.println(name); // 局部变量
System.out.println(this.name); // 本类
System.out.println(super.name); // 父类
}
}

方法重写

覆盖虚方法里的同名方法,在子类的子类中的方法就是覆盖后的虚方法表

子类重写父类的方法,访问控制方法必须大于父类 无<protect<public

@Override

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Fu {
public void f() {
System.out.println(1);
}
}
class Zi extends Fu {
@Override
public void f() {
System.out.println(2);
}

public void show() {
f();
}
}

父类空参构造

super(可带参); 视父类的构造函数而定

super() 无参构造 不写系统默认添加

多态

父类类型 对象名 = 子类对象;

Fu f = new Zi();

一对多系统

调用父类成员,父类中没有成员,直接爆错

调用方法,父类没有(虚方法表没有),直接报错,调用子类方法 父类也必须有 子类加上@Override

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
pulic static void main(String[] args) {
Fu f = new Zi();
f.eat(); // 调用Fu里的eat() 输出吃
}
class Fu{
public void eat(){
sout("吃");
}
}

class Zi extends Fu{
public void eat() {
sout("喝");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pulic static void main(String[] args) {
Fu f = new Zi();
f.eat(); // 调用Zi里的eat() 输出喝
}
class Fu{
public void eat(){
sout("吃");
}
}

class Zi extends Fu{
@Override //
public void eat() {
sout("喝");
}
}

instanceof 类之间的类型转换

判断对象类

对象 instanceof 类名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
pulic static void main(String[] args) {
Fu f = new Zi();
Fu g = new Nu();

// 强转
if (f instanceos Zi){
Zi c = (Zi) f;
可调用方法
}
else{
Nu c = (Nu) f;
可调用方法
}

// JDK14之后
if (f instanceos Zi c){
可调用方法
}
else if(f instanceos Nu c){
可调用方法
}

}


class Fu{
public void eat(){
sout("吃");
}
}

class Zi extends Fu{
public void eat() {
sout("喝");
}
}

class Nu extends Fu{
public void eat() {
sout("喝");
}
}

类的自动类型转换和强制类型转换

自动类型转换

1
2
Person 是父类  Student 是子类
Person p = new Student();

强制类型转换

1
2
Person 是父类  Student 是子类
Student s = (Student) p;

final

修饰的方法不能被从写

修饰的类不能被继承

修饰的变量变常量

修饰的引用数据类型,地址值不能改变,属性可以改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Person{
....
}

final String s = new Person("zhangsan","33");

s.setName = "lisi";
s.SetAge = "44";
sout(s.getName+s.getAge);
改变之后的值


数组
final int[] arr = {1,2,3};
arr[0] = 4;
arr[1] = 5;
索引 0 1 的值被修改

修饰符

private 同一个类中

空 同一个包中

protect 同一个包中 和 不同包下的子类

public all 和 不同包下 的无关类

abstract

修饰的方法必须重写

1
public abstract void f();

抽象类

1
public abstract class f{}

抽象类不能实例化

抽象类中 可以有抽象方法,有抽象方法的类一定是抽象类

可以有构造方法

抽象类的子类,要么重写抽象方法,要么是抽象类

1
2
3
4
public class Person{
public abstract void work();
}
报错,不是抽象类,但有抽象方法

可以有构造方法

1
2
3
4
5
6
7
8
public abstract class Person{
private name;

public Person(){}
public Person(String name){
this.name = name;
}
}

interface 接口

接口里的成员只能时常量

默认修饰符 public static final

没有构造方法

成员方法 只能时抽象方法

方法默认修饰符 public abstract

1
2
3
4
5
6
7
8
9
public interpace swim{
public abstract void swim();
}

class f extends Animal implements swim,接口2……{ // 接口可以有多个
public void swim(){
sout("f在游泳");
}
}

jdk7 之前 接口中只能写抽象方法

jdk8 接口中可以定义有方法体的方法

jdlk9 接口中可以定义私有方法

接口和类之间的关系

类和类 继承

类和接口 实现关系 可实现多个接口

接口和接口 继承 可以多继承

jdk7 之前 接口里面的方法必须重写 无方法体

jdk8 不强制重写 要用default修饰(重写时去掉) 有方法体 public default void show() {}

调用多个接口 有同名方法 必须重写

接口中的私有方法

不能重写 可以同名

jdk9 私有方法

只能给 default方法 调用

private 返回值类型 方法名() {}

静态方法只能调用静态方法

private static 返回值类型 方法名() {}

适配器

抽象类+接口

内部类

写在类里的类,engine 是 car 的一部分

1
2
3
4
5
6
7
8
9
10
11
12
public class Car {
private a;
private b;
public void show(){
sout('1');
}
public class engine { // 内部类
public void show(){
sout('2');
}
}
}

定义

1
2
3
4
5
public class Test {
public static void main(String[] args) {
Car.engine c = new Car().new engine();
}
}

静态内部类

只能访问外部类的静态成员和方法,访问非静态要创建对象

1
2
创建对象
Car.engine c = new Car.engine();

调用方法

1
2
3
4
非静态方法
创建对象,用对象调用
静态方法
外部类.内部类名.方法名();

局部内部类

定义在方法里的类

外部无法使用 方法内部创建对象使用

可以直接访问外部类成员 也可以访问方法内的局部变量

没什么用 了解一下

匿名内部类

1
2
3
4
5
6
7
8
public aaa {
new bbb() {
@Overide
puclic void ccc() {
sout(1);
}
}
}

bbb是一个接口 接口调用 新建对象

ccc是bbb中的方法

1
2
3
4
5
6
7
8
public aaa {
new bbb() {
@Overide
puclic void ccc() {
sout(1);
}
}
}

bbb是一个抽象类 继承关系 新建对象

方法需要调用的少

1
2
3
4
5
6
7
8
9
10
11
12
public static void method(aaa a) {
a.eat();
}

method(
new aaa() {
@Override
public void eat() {
sout(1);
}
}
);

aaa 是同包下的一个外部类

1
2
3
4
5
6
7
8
method(
new aaa() {
@Override
public void eat() {
sout(1);
}
}
).方法();

番外 调用方法

隐藏了名字的内部类 可以写在成员位置和局部位置

当方法的参数是接口或类时,

以接口为例,可以传递这个接口的实现类对象,

如果实现类只要使用一次,就可以用匿名内部类简化代码

⬆︎TOP