Java学习
要了解Android先从Java学起吧
JDK开发 JRE运行
class java最基本的单元;字符串双引号 字符单引号;一个class文件下只能有一个public class
\t 制表符 可用单双号引起来 把String长度补到8x
数据类型需要赋值 float 和 long加后缀 标识符区分大小写
接收输入 import java.util.Scanner; Scanner sc = new Scanner(System.in); int i = sc.nextInt();
project module模块(新建File->structure) package包 class类(文件名和类名一致)
psvm or main, sout可以直接回车
字面量literal:字符单引号 ;0b 0 0x对应二八十六进制
标识符:不能数字开头 变量名方法名小驼峰 类名大驼峰
方法:
修饰符 返回值类型 方法名(形参列表) {方法代码 return 结果}
变量:
成员变量
静态成员变量:全部对象共享
实例成员变量:每个对象独有
局部变量:方法中的变量
基本类型变量:int char etc
引用类型变量:数组 对象
byte short char 在表达式中都自动转换成int运算;
逻辑运算符 & | ^ !&& || 后二者可以仅判断左边
switch不支持double float long
静态数组eg String[] name = {} or String[] name = new String[]{} or String name[] = new String[]{}
动态数组eg String[] name = new String[9]
二维静态数组String[][]={{}}
二维动态数组String[][]= new String[3][7]
Arrays.toString()可以返回数组内容 然后sout
类(对象是类的实例)的基本语法:
1⃣️构造器or构造方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class Student {
//构造器无返回值,name和类名相同,可重载;无参构造器自带;有有参构造器则无参构造器默认无
String name;
int age;
char gender;
public Student(){
System.out.println("this is constructor without parameter");
}
public Student(String name){
System.out.println("this is constructor with parameter:"+name);
}
public Student(String n,int a,char g){
System.out.println("this is constructor with parameter:"+n+a+g);
name = n;
age = a;
gender = g;
}
}
//可以通过this在一个类中调用兄弟构造器,写在构造器第一行2⃣️this:
1
2
3
4
5
6
7public class Student {
//this是一个变量 用于拿到当前对象
String name;
public void print(String name){//这里的name是歌名
System.out.println(this.name+"喜欢"+name);
}
}3⃣️封装capsulation(面向对象三大特征:封装 多态 继承):就是权限修饰符private
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public class Student {
//使用private对变量合理隐藏
private String name;
private int age;
//如何暴露private:使用public修饰的get和set
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}4⃣️实体类Javabean:成员变量全部私有,有get&set,必须有无参构造器
5⃣️static:
静态变量(类变量):被全部的对象共享
实例变量(对象的变量):每个对象有自己的
静态方法:属于类 可用类名.方法名使用;静态方法中只可以有静态变量/方法;静态方法中不可以使用this
实例方法:属于对象
工具类:包含一些静态方法,工具类的构造器可以直接私有
6⃣️继承extends:继承非私有成员;子类父类成员名字重复时,在子类访问父类的成员可用super.成员名
方法重写:方法的名称和参数列表必须一样,前一行加上@override,子类重写的方法访问权限需要大于等于父类,返回值类型要比父类相等或更小,私有方法和静态方法不能重写
子类构造器:先调用父类构造器,再调用子类构造器。如果父类有无参构造器,则子类会默认第一行super();;如果父类没有无参构造器,则需要在子类构造器的第一行super(…)(必须写在构造器第一行)调用父类有参构造器。
7⃣️多态polymorphsm:使用父类类型作为参数,可以接受一切子类对象;多态对象不能调用子类独有功能;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class Test {
public static void main(String[] args) {
//1.对象多态
Animal a1 = new Wolf();
Animal a2 = new Totoise();
//2.行为(方法)多态,编译看左,运行看右
a1.run();
a2.run();
//3.使用父类类型作为参数,可以接受一切子类对象
go(a1);
}
public static void go(Animal animal){
System.out.println("使用父类类型作为参数,可以接受一切子类对象");
animal.run();
}
}1
2
3
4
5public class Animal {
public void run(){
System.out.println("this is Animal class");
}
}1
2
3
4
5
6public class Totoise extends Animal{
@Override
public void run(){
System.out.println("this is Totoise class");
}
}1
2
3
4
5
6
7public class Wolf extends Animal {
@Override
public void run(){
System.out.println("this is Wolf class");
}
}this is Wolf class
this is Totoise class
使用父类类型作为参数,可以接受一切子类对象
this is Wolf class多态下的类型转换(强转后调用子类独有功能):强制从父类转化到子类 子类 变量名 = (子类)父类变量 (只能强转为原定义时等号右边的类型)
强制转换前可以使用intenceof判断(判断原等式右边的类型):
1
2
3
4
5
6
7if(a1 instanceof Wolf){
WoLf w1 = (Wolf) a1;
w1.eatsheep();
}else if(a1 instanceof Tortoise){
Tortoise tl = (Tortoise) a1;
t1.run()
};8⃣️权限修饰符:private(只能本类)<缺省(本类、同包下的类)<protected(本类、同包下的类、子孙类)<public
final关键字:
最终类:不可以被继承
最终方法:不可以被重写
被修饰变量:仅可以被赋值一次
final修饰的基本类型变量不可以再次赋值,修饰的引用类型变量的地址是固定的但可以再次赋值。
static final修饰的为常量(命名全大写)
单例类(设计模式是解决问题的方案,单例是其中一种):
1
2
3
4
5
6
7
8
9
10
11public class A {
//1.定义一个静态变量,用于构建本类的唯一对象
private static A a = new A();
//2.私有化构造器,确保外部不可创建对象
private A(){
}
//3.提供一个静态方法用来返回唯一的对象
public static A getInstance(){
return a;
}
}枚举类:
1
2
3public enum A{
X,Y,Z;
}枚举类的第一行必须是名称,对应对象(对象是public static final的)
枚举类都是最终类,不可以被继承
构造器私有,不用写,不可以创建对象
1
2
3
4
5
6
7
8
9
10
11public static void main(String[] args){
// 目标:认识枚举类,搞清楚其本质特点。
A a1 = A.X;
System.out.printin(a1);//X
A a2 = A.Y;
System.out.printin(a2);//Y
System.out.println(a1.name());//X
System.out.println(a2.name());//Y
System.out.printin(a1.ordinal());//索引0
System.out.println(a2.ordinal());//索列1
}抽象类abstract:抽象类不能建立对象(可以用父类名创建对象),只能作为父类让子类继承
可以修饰类和成员方法,修饰成员方法只有方法签名而没有方法体(不用写大括号但需写分号)
抽 象类中不一定有抽象方法,但抽象方法必须在抽象类中
一个类继承抽象类必须重写父类中全部抽象方法
应用场景:父类知道每一个子类的动作但不知道子类具体要做什么
模版方法(也是一个设计模式):适用于父类部分内容需要重写的情况
1
2
3
4
5
6public class Test {
public static void main(String[] args) {
Student s1 = new Student() ;
s1.write();
}
}1
2
3
4
5
6
7
8
9
10public abstract class People {
//模版方法设计模式
public final void write(){//加个final防止被重写
System.out.println("这里的内容是不同的身份都一样的 ");
//以下 内容是每个子类都写,但是内容不同的;这里父类写一个抽象方法,具体实现交给子类
writeMain();
System.out.println("这里的内容也是不同的身份都一样的 ");
}
public abstract void writeMain();
}1
2
3
4
5
6public class Student extends People{
@Override
public void writeMain(){
System.out.println("这是学生的正文");
}
}1
2
3
4
5
6public class Teacher extends People{
@Override
public void writeMain(){
System.out.println("这是老师的正文");
}
}这里的内容是不同的身份都一样的
这是学生的正文
这里的内容也是不同的身份都一样的接口interface: 接口不能创建对象
public interface 接口名{
//传统接口JDK8只能写常量和抽象方法
//接口中常量不用写public final static
//接口中抽象方法不用写public abstract
//JDK8之后新增默认方法(default 默认用public修饰,只能用接口的实现类来调用) 私有方法(只能用接口中的其他实例方法来调用) 静态方法(默认public,只能使用接口名调用 )
}
接口用来被类实现,实现接口的类叫实现类,一个实现类可以实现多个接口
作用:可以将接口规定的方法功能给多个类实现 方便切换业务
接口与抽象类对比
相同点:
1、多是抽象形式,都可以有抽象方法,都不能创建对象。
2、都是派生子类形式:抽象类是被子类继承使用,接口是被实现类实现。
3、一个类继承抽象类,或者实现接口,都必须重写完他们的抽象方法,否则自己要成为抽象类或者报错!
4、都能支持的多态,都能够实现解耦合。不同点:
1、抽象类中可以定义类的全部普通成员,接口只能定义常量,抽象方法(JDK8新增的三种方式)2、抽象类只能被类单继承,接口可以被类多实现。
3、一个类继承抽象类就不能再继承其他类,一个类实现了接口(还可以继承其他类或者实现其他接口)。
4、抽象类体现模板思想:更利于做父类,实现代码的复用性。
5、接口更适合做功能的解耦合:解耦合性更强更灵活。代码块(类中的成分):
静态代码块static{}
特点:只在最初执行一次,用于完成类的一些初始化操作
实例代码块{}
特点:每次创建对象时执行,在构造器前执行,用于完成类的一些初始化操作
内部类
成员内部类:
创建对象的格式:外部类名.内部类名 对象名 = new 外部类(…).new 内部类(…);
成员内部类访问外部类成员的特点(拓展):1、成员内部类中(的方法)可以直接访问外部类的静态成员(变量和方法),也可以访问类的实例成员
2、成员内部类的实例方法中,可以直接拿到当前寄生的外部类对象: 外部类名.this
静态内部类:
public static class 属于外部类本身所有
外部类名.内部类名 对象名=new 外部类.内部类(..);
可以直接访问外部类的静态成员,不可以访问类的实例成员(实例成员属于外部类对象所有 )
局部内部类:
在方法、代码块、构造器等执行体中的内部类
匿名内部类:
是一种特殊的局部内部类 不需要单独为它声明名字 本质是子类 会立即创建一个子类对象
new 类或接口(){
//类体(一般是重写)
};
函数式编程:
lambda
java中的函数就是lambda表达式
(被重写方法的形参列表)->{
被重写方法的方法体代码
};
lambda只能简化函数式接口(有且仅有一个抽象方法的接口 @FunctionalInterface)的匿名内部类
注意事项:
参数类型全部可以省略不写。
如果只有一个参数,参数类型省略的同时“()”也可以省略,但多个参数不能省略“()”
如果Lambda表达式中只有一行代码,大括号可以不写,同时要省略分号”;”如果这行代码是return语句,也必须去掉return。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class Test1 {
public static void main(String[] args) {
Student[] s = new Student[3];
s[0] = new Student("Jerry",18,'m');
s[1] = new Student("Tom",19,'w');
s[2] = new Student("Jack",20,'m');
// Arrays.sort(s, (Student o1,Student o2)->{
// return o2.getAge()-o1.getAge();
// });//按年龄降序
Arrays.sort(s, (o1,o2)->o2.getAge()-o1.getAge());//按年龄降序
for (int i = 0; i < s.length; i++) {
Student stu = s[i];
System.out.println(Arrays.toString(new Student[]{stu}));
}
}
}方法引用
用来简化lambda的
静态方法引用
类名::静态方法
如果Lambda表达式只是调用一个静态方法,并且->前后的参数形式一致,则可以使用静态方法。
实例方法引用
对象名:: 实例方法
如果某个Lambda表达式里只是通过对象名称调用一个实例方法,并且->前后参数的形式一致,就可以使用实例方法引用。
特定类方法引用
特定类名称::方法
如果某个Lambda表达式里只是调用一个特定类型的实例方法,并且前面参数列表中的第一个参数是作为方法的主调,后面的所有参数都是作为该实例方法的入参的,则此时就可以使用特定类型的方法引用。
例子:
1
Arrays.sort(names,String::compareToIngoreCase);构造器引用
类名::new
如果某个Lambda表达式里只是在创建对象,并且->前后参数情况一致,就可以使用构造器引用。
常用API
字符串内容比较不用==(==会比较地址),字符串内容对比用.equals()
.charAt()获得对应位置的字符
ArrayList集合:是一种容器,类似数组
1
ArrayList<String> list = new ArrayList<>();方法 描述 add() 将元素插入到指定位置的 arraylist 中 addAll() 添加集合中的所有元素到 arraylist 中 clear() 删除 arraylist 中的所有元素 clone() 复制一份 arraylist contains() 判断元素是否在 arraylist get() 通过索引值获取 arraylist 中的元素 indexOf()) 返回 arraylist 中元素的索引值 removeAll() 删除存在于指定集合中的 arraylist 里的所有元素 remove() 删除 arraylist 里的单个元素 size() 返回 arraylist 里元素数量 isEmpty() 判断 arraylist 是否为空 subList() 截取部分 arraylist 的元素 set() 替换 arraylist 中指定索引的元素 sort() 对 arraylist 元素进行排序 toArray() 将 arraylist 转换为数组 toString() 将 arraylist 转换为字符串 ensureCapacity 设置指定容量大小的 arraylist lastIndexOf() 返回指定元素在 arraylist 中最后一次出现的位置 retainAll() 保留 arraylist 中在指定集合中也存在的那些元素 containsAll() 查看 arraylist 是否包含指定集合中的所有元素 trimToSize() 将 arraylist 中的容量调整为数组中的元素个数 removeRange() 删除 arraylist 中指定索引之间存在的元素 replaceAll() 将给定的操作内容替换掉数组中每一个元素 removeIf() 删除所有满足特定条件的 arraylist 元素 forEach() 遍历 arraylist 中每一个元素并执行特定操作