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 {
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),最大值 127(2^7-1),默认值 0 byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一; 例子:byte a = 100,byte b = -50 short short 数据类型是 16 位、有符号的以二进制补码表示的整数 -32768(-2^15),32767(2^15 - 1),0 一个short变量是int型变量所占空间的二分之一 int int 32位,…… -2,147,483,648(-2^31),2,147,483,647(2^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 字面量,而 7D,7. 和 8.0 是 double 字面量。
boolean boolean数据类型表示一位的信息; 只有两个取值:true 和 false; 这种类型只作为一种标志来记录 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(条件表达式){ .... }else if(条件表达式){ .... }... else{ .... }
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 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 2 3 4 5 6 7
| public static void 方法名(数据类型 形参){ .... }
public static void 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);
boolean r = s1.equals(s2); sout(r);
|
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); sout(sb.reverse()); sout(sb.length()); 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<>();
ArrayList<String> list = new ArrayList<>(); 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] [ccc] [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(); } 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(); } 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; 可调用方法 }
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); } } ).方法();
|
番外 调用方法
隐藏了名字的内部类 可以写在成员位置和局部位置
当方法的参数是接口或类时,
以接口为例,可以传递这个接口的实现类对象,
如果实现类只要使用一次,就可以用匿名内部类简化代码