IDEA快捷键
- option+command+左键点击 跳转
- shift+fn+F6 全局修改名字
- command+N 新建
- ctrl+option+i 格式化
- shift+ctrl+R 运行
- shift+cmooand+up/down 某行上下移动
- tab 向后缩近 shift+tab 向前缩近
- option+enter 处理代码报错
- 函数上
/**函数方法注释
- ctrl+h 查看继承类
IDEA代码提速
JAVA运行
- JVM, Jave Virtual Machine,Java虚拟机,在对应平台上翻译Java,实现跨平台
- JRE,Java Development Environment,运行环境
- JDK, Java Development Kit,开发工具包
- JDK包含开发工具和JRE,JRE包含JVM和核心类库
HelloWorld
重载
- overload,放个方法名一样,但是参数列表不一样
- 只需要一个唯一的方法名称,就可以实现多个类似的但是不同的功能
- 参数个数不同;参数类型不同;参数的多类型顺序不同
- 与参数的名称无关;与方法的返回值类型无关
数据类型默认值
- 整数,0
- 浮点,0.0
- 字符,'\u0000'
- 布尔,false
- 引用,null
Java内存
- 栈 stack,存放的都是方法中的局部变量。局部变量有作用域,一旦超出作用域,立即从栈内存当中小时。进栈为压栈,先进后出
- 堆 heap,凡是new出来的东西都有一个地址值,16进制。
- 方法区 Method Area,存储.class相关,包含方法的信息
- 本地方法栈 Native Method Stack,与操作系统相关
- 寄存器 pc Register,CPU相关

数组
- 数组长度,在程序运行期间不可改变
- length获取数组长度
- 数组作为方法参数的原理,传递进去的是数组的地址值,方法通过地址值访问数组
类与对象
- 类,对一类事物的描述,抽象的,图纸
- 对象,是一类事物的实例,具体的,根据图纸设计的实体
- 类是对象的模板,对象是类的实体
- 对象包括属性和行为,属性(成员变量)指
是什么,行为(成员方法)指能做什么
类的内存空间
- 成员变量存放在堆中
- 成员方法以指针地址的方式存在堆中,指向方法区的实际方法

getter与setter
- 基本数据类型boolean类型,getter方法要写成isXxx方法
this关键字
- 指出本类当中的成员变量
- 通过谁调用,谁就是this
- 可以在本类的构造方法中,访问另一个构造方法,但是也必须是第一个语句
构造方法
- 在初始值赋值后,才进行构造方法
- public 类名称(参数类型 参数名称) {方法体}
- 构造方法的名称必须和类名完全一样
- 构造方法不要写返回值类型,void都不行
- 不能return一个返回值
- 如果没有编写任何构造方法,编译器会默认赠送一个构造方法,什么都不做
- 一旦编写了构造方法,将不再赠送
- 构造方法可以重载
标准的类
- 所有成员变量都要使用private修饰
- 为每一个成员变量编写一对getter/setter
- 无参数的构造方法
- 全参数的构造方法
- 在代码面 command+N 自动生成
局部变量与成员变量
- 定义的位置不一样
- 局部变量:在方法的内部
- 成员变量:在方法的外部,直接写在类中
- 作用范围不一样
- 局部变量:只有方法当中才可以使用,出了方法不行
- 成员变量:整个类全部可以使用
- 默认值不一样
- 局部变量:没有默认值,如果想要使用,必须手动赋值
- 成员变量:如果没有赋值,会赋默认值
- 内存的位置不一样
- 生命周期不一样
- 局部变量:随着方法进栈诞生,随着方法出栈小时
- 成员变量:随着对象创建诞生,随着对象被垃圾回收消失
匿名对象
- 只有右边的对象,没有左边的名字和赋值运算符
- 如果确定有一个对象只需要使用唯一的一次,就可以使用匿名对象
static关键字
- 类中用static修饰后的成员变量,不再属于对象,而是属于类,凡事本类实例化后的对象,都共享同一份
- 类中用static修饰后的成员方法,在使用的时候,可以直接通过类名称直接调用,类似类方法
- 静态不能直接访问静态,成员方法可以访问静态变量,静态方法不能访问非静态成员变量
- 内存中,先有的静态内容,后有的非静态内容
- 静态方法中,不能使用this关键字

静态代码块
- 当第一次使用本类时,静态代码块唯一的执行一次
- 静态内容,总是优先于非静态
- 用来一次性地对静态变量进行赋值
static {
System.out.println("i am static code");
}
面向对象
封装
- 方法就是一种封装
- 关键字private也是一种封装
- 将一些细节信息隐藏起来,对外界不可见
继承
- 继承是多态的提前,如果没有继承,就没有多态
- 继承主要解决
共性抽取的问题
- 父类/子类;基类、超类/派生类
- 子类可以拥有父类的内容;子类可以拥有自己专有的内容
- 子类就是一个父类,子类可以被当作父类看待
访问成员变量
- 直接通过对象访问成员变量,等号左边是谁,就优先用谁,没有则向上找
- 间接通过成员方法访问成员变量,方法属于谁优先用谁的成员变量,没有则向上找
区分父子类成员变量
- 直接局部变量名
- this.子类成员变量
- super.父类成员变量
public void method() {
String name = "zhangsan";
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
成员方法
重写
- 覆盖,覆写
- override,在继承关系中,方法的名称一样,参数列表也一样
- @Override 写在方法前面,检测是否重写成功
- 子类方法的返回值,必须
小于等于父类方法的返回值范围
- 子类方法的权限必须
大于等于父类方法的权限修饰符 public > protected > (default 留空) > private
设计原则
- 对于已经投入使用的类,不要进行修改,定义一个新的类,来重复利用其中的共性内容,并添加新内容
构造方法
- 如果父类只有
有参构造,子类必须覆盖重写
- 子类构造方法中,会默认先调用父类构造方法,所以在实例化过程中,会先调用父类构造方法,再调用子类构造方法
- 子类必须调用父类构造方法,不写则赠送super(),写了则用指定的super调用,并且有且只能有一个,且在子类构造方法的第一句
- super和this两种构造调用,但是只能选一种

继承特点
- 单继承,一个类的直接父类只能有唯一一个
- 多级继承,可以有多层的继承
- 一个父类可以拥有很多个子类
抽象类
- 如果父类的方法不能具体实现,则为抽象方法
- 抽象方法所在类,必须是抽象类,
abstract
- 抽象类中可以有构造方法,但是只能通过子类构造方法进行调用
- 抽象类不能直接创建对象
- 抽象类的子类,必须重写抽象父类的抽象方法,除非子类也是抽象类
接口
- Interface
- 类似ios中的协议
- 接口不能有静态方法块;不能有构造方法
- 一个类可以同时实现多个接口,如果多个接口有同样的抽象方法,实现类中会进行统一重写覆盖;有同样的默认方法,一定要进行覆盖重写
- 如果一个类的父类和接口类,方法冲突,优先父类方法
- 公共的规范标准
- 引用数据类型
- 实现类,
implements
- 包括 常量,抽象方法,默认方法,静态方法,私有方法
public abstract void abstractMethod();
public default void defaultMethod() {
System.out.println("默认方法");
}
public static void staticMethod() {
System.out.println("静态方法");
}
private void privateMethod() {
System.out.println("privateMethod");
}
private static void privateStaticMethod() {
System.out.println("privateStaticMethod");
}
- 接口中的成员变量只能是常量,
public static final,一旦赋值,不可改变;必须进行赋值;
public static final int num = 10;
多态
extends继承和implements实现,是多态性的前提
- 父类引用指向子类对象,
父类名称 对象名 = new 子类名称()
- 成员方法,编译看左,运行看右。
- 编译时看左边有没有需要调用的内容,如果没有则报错;
- 运行时,在右边的空间进行查找
- 父类调用子类特有的方法,编译报错;因为编译时,在父类找不到子类特有方法
- 直接调用,等号左边是谁,就找谁的,没有则向上找,父类引用在子类的空间中调用了父类的成员
- 间接调用,方法属于谁,调用谁,没有就向上找
- 成员变量是没有覆盖重写的
- 统一左边
- 向上转型,父类引用指向子类对象,一定是安全的,从小范围转向了大范围,但是无法调用子类特有的方法
- 向下转型,还原的动作。
子类名称 对象名 = (子类名称)父类对象,目标要与右边类统一
//判断是否属于目标对象,不是则返回-1
if (animal instanceof Cat) {
Cat cat = (Cat) animal
cat.catchFish()
}
if (animal instanceof Dog) {
Dog dog = (Dog) animal
dog.bark()
}
API
- Application Programming Interface, 应用程序编程接口,SDK自带的方法
一般使用步骤
- 导包,如果当前类位于同一个包下,不需要导包;只用lava.lang包下的内容不需要导包,其他都需要
- 创建
- 使用
Scanner
import java.util.Scanner
//System.in 从键盘输入
Scanner scanner = new Scanner(System.in)
int num = scanner.nextInt()
System.out.println(num)
String str = scanner.next()
System.out.println(str)
random
Random random = new Random()
//正负都有可能
int res = random.nextInt()
System.out.println(res)
Random random = new Random()
int res = random.nextInt(3)
System.out.println(res)
arrayList
- 集合的长度可以随意变化
- 存的内容全部要是同一类型,并且只能是引用类型,不能是基本类型
存自定义对象
ArrayList<Person> persons = new ArrayList<>();
for (int i = 0; i < 10; i++) {
persons.add(new Person("xiaoming-" + i, 100 / (i + 1)));
}
persons.add(1,new Person("xiaozhang", 20));
for (int i = 0; i < persons.size(); i++) {
System.out.println(persons.get(i).getName() + "-----" + persons.get(i).getAge());
}
String removedName = persons.remove(3).getName();
System.out.println(removedName + " - 被删掉");
for (int i = 0; i < persons.size(); i++) {
System.out.println(persons.get(i).getName() + "-----" + persons.get(i).getAge());
}
存基本数据类型
- 如果要想ArrayList存储基本类型,必须使用基本类型对应的包装类
- 自动装箱,基本数据类型->包装类型
- 自动拆箱,包装类型->基本数据类型
基本数据类型 包装类(引用类型)
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
ArrayList<Integer> ints = new ArrayList<>()
ints.add(100)
ints.add(200)
System.out.println(ints)
int num = ints.get(1)
System.out.println(num)
String
- 程序中所有双引号的字符串都是String对象,创建之后都不能更改
- 字符串不可改变,所以字符串是可以共享使用的
- 字符串的效果相当于char[]字符数组,但底层原理是byte[]字节数组
创建方式
//空参构造函数创建
String str1 = new String()
//根据字符数组创建字符串
char[] charArr ={'h', 'w', 'm'}
String str2 = new String(charArr)
System.out.println(str2)
//根据字节数组创建字符串
byte[] byteArr = {90, 87, 85}
String str3 = new String(byteArr)
System.out.println(str3)
//直接创建
String str4 = "hello world"
字符串常量池
- 程序当中直接写上的双引号字符串,就在字符串常量池中
- 对于基本类型,==是进行数值比较;对于引用类型,==是进行地址值的比较
- 直接new的字符串对象,不在常量池中

常用方法
String str1 = "hello"
String str2 = "hello"
String str4 = "HeLLO"
char[] chars = {'h', 'e', 'l', 'l', 'o'}
String str3 = new String(chars)
System.out.println(str1.equals(str2))
System.out.println(str1.equals(str3))
System.out.println(str3.equals("hello"))
//推荐方式
System.out.println("hello".equals(str2))
//忽略大小写
System.out.println("hello".equalsIgnoreCase(str4))
String str = "dwaiojdpoawjpeakw"
System.out.println(str.length())
//str1 str2不变
String str1 = "hello"
String str2 = "world"
String str3 = str1.concat(str2)
System.out.println(str3)
char c = "hello".charAt(4)
System.out.println(c)
//找不到返回-1
String str = "dwaiojdpoawjpeakw"
int index = str.indexOf("jpea")
System.out.println(index)
String str = "helloworld"
String subStr1 = str.substring(2)
//左闭,右开
String subStr2 = str.substring(5,9)
System.out.println(subStr1)
System.out.println(subStr2)
String str = "helloworld"
//转换成char数组
char[] chars = str.toCharArray()
//转换成byte数组
byte[] bytes = str.getBytes()
//替换字符串
String newStr1 = str.replace(str, "javaHello")
//替换字符
String newStr2 = str.replace('o', 'm')
for (int i = 0
System.out.println(chars[i])
}
for (int i = 0
System.out.println(bytes[i])
}
System.out.println(newStr1)
System.out.println(newStr2)
- 字符串分割
- split方法的参数其实是一个正则表达式,
.无法切割,要用\\.进行转义
String str = "hel, low, orld"
//根据某个字符串进行切割
String[] strings1 = str.split(", ")
//限制返回的字符串数量
String[] strings2 = str.split(",", 2)
for (int i = 0
System.out.println(strings1[i])
}
for (int i = 0
System.out.println(strings2[i])
}
Arrarys
- 如果是数值,按照升序
- 如果是字符串,按照字母升序
- 如果是自定义的类型,自定义类需要有
Comparable或者Comparator接口的支持
int[] ints = {10, 20, 30}
//将int[] 按照默认格式变成字符串 [10, 20, 30]
String intStr = Arrays.toString(ints)
System.out.println(intStr)
//排序
int[] ints1 = {2,3,5,7,1,2,0,10}
Arrays.sort(ints1)
System.out.println(Arrays.toString(ints1))
Math
System.out.println(Math.abs(-2.9));
System.out.println(Math.ceil(4.2));
System.out.println(Math.floor(4.9));
System.out.println(Math.round(4.6));
System.out.println(Math.round(3.4));
System.out.println(Math.PI);
Final关键字
- 修饰类,不能有任何子类
- 修饰方法,不能被覆盖重写
- 修饰局部变量,一次赋值,终身不变;对于基本类型,不可变指的是数据不可改变;对于引用类型,不可变指的是地址值不可改变
- 修饰成员变量,变量不可变,但是必须手动赋值,不会给默认值;否则,必须在所有的构造方法内都进行赋值
权限修饰符
- 访问权限
|| public | protected | defalut | private |
|:---:| :---:|:---:|:---:|:---:|
|同一个类| Y | Y | Y | Y |
|同一个包| Y | Y | Y | N |
|不同包子类| Y | Y | N | N |
|不同包非子类| Y | N | N | N |
内部类
成员内部类
- 内用外,随意访问
- 外用内,要借助内部类对象
- 内部类和外部类调用
//间接调用内部类
Body b = new Body()
b.methodBody()
//直接调用内部类
Body.Heart bh = new Body().new Heart()
bh.methodHeart()
System.out.println(name);
System.out.println(this.name);
System.out.println(Body.this.name);
局部内部类(匿名内部类)
- 定义在方法内部
- 只有当前所属的方法才能使用它,出了这个方法就不可以
- Body中的方法局部内部类
public void methodInner() {
class Lungs {
String name = "wangwu";
public void methodLungs() {
System.out.println("methodLungs");
System.out.println(this.name);
}
}
Lungs l = new Lungs();
l.methodLungs();
}
- 局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是
有效final,即只能被赋值一次
- 原因是,new出来的对象是在堆中,局部变量是跟着方法走的,在栈内存中,方法运行结束之后立即出栈,局部变量消失,但是new出来的对象会在堆中持续存在,直到,垃圾回收,所以要保证
在局部内部类存在期间,局部变量存在,即局部变量的内容不能改变,copy进内部类一份
匿名内部类
- 直接在方法内使用接口实现类或者抽象类实例化
- 可以减少实现类的创建,省略了实现类或者子类
- 接口名称 对象名 = new 接口名称() { 覆盖重写所有抽象方法 }
MyInterface obj = new MyInterface() {
@Override
public void method() {
System.out.println("anonymousMethod");
}
};
obj.method();
new MyInterface() {
@Override
public void method() {
System.out.println("anonymousMethod");
}
}.method();
- 匿名内部类,在创建对象的时候,
只能使用唯一一次
- 匿名对象,
只能调用唯一一次,如果希望调用多次,那就取个名字
类的权限修饰符
- 外部类 public/default
- 成员内部类 public/protected/default/private
- 局部内部类 类似局部变量,什么都不写