1、类变量和类方法
2、类变量
1、设置后被所有对象实例共享(static变量是对象共享)//同一类中
2、static类变量,在类加载的时候就生成了。//所有在不对象实例化下就可以对象名.类变量
2.1、类变量的内存剖析

1、有说在堆空间中的类中 //1.8版本以后
2、又说是在常量池中(静态域中)
2.2、类变量的定义和访问
1、定义语法:
(1)访问修饰符 static 数据类型 变量名 ;【推荐】
(2)static 访问修饰符 数据类型 变量名 ;
2、如何访问
(1)类名.类名变量
(2)对象名.类变量名(和普通访问一样)
(3)类名.类变量名
注:类变量遵守权限修饰符的规则
2.3、类变量的使用细节
1、类变量是本类所有对象都可以调用的
2、类变量和实例变量(普通属性)的区别
(1)类变量是该类所有的对象都可以访问
(2)实例变量是每个对象独享的。
3、实例变量(普通变量)不能通过 类名.类变量 方式访问
4、类变量是在类加载的时候就初始化了,即使没有创建对象,只要类加载了,就可以使用类变量了
5、类变量的生命周期是随类的加载开始,随着类消亡而销毁。
3、类方法(静态方法)
3.1、基本用法
1、类方法也叫静态方法
2、操作
(1) 访问修饰符 static 数据返回类型 方法名(){}【推荐】
(2) static 访问修饰符 数据返回类型 方法名(){}
3、调用
(1)类名.类方法名
(2)对象名.类方法名
4、小结
在程序员实际开发,往往会将一些通用的方法,设计成静态方法,这样我们不需要创建对象就可以使用了,比如打印一位数组,冒泡排序,完成某个计算任务等。
3.2、注意事项
1、类方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区。
2、类方法中没有this和super参数、普通方法隐含this和super的参数
3、普通方法不能通过类名调用,类方法可以
4、静态方法中只能访问静态变量或静态方法
5、普通的成员(变量、方法),既可访问非静态成员,也可以访问静态成员
总结:静态方法,只能访问静态的成员,非静态的方法,可以访问静态测验和非静态测验(必须遵守访问权限)
3.3、理解 main方法的语法
1、java虚拟机调用mian方法
2、因为虚拟机和main方法不是一个类,所有要用:public
3、static:是不需要创建对象来调用,直接想调用
4、该方法接收String类型的数组参数,该数组中保存执行了java命令时,传递给所有运行的类的参数
(1)可以在cmd中输入和取出数组存放的参数

(2)也可以在idea中操作


5、静态方法不能直接访问非静态方法和变量,但是可以通过实例化对象(对象.方法/属性)去调用
4、代码块
4.1、基本介绍
(1)又称为初始化块,属于类中的成员【即是类的一部分】将逻辑结构封装在方法体中,通过{}包围起来
(2)方法不同,没有方法名,没有返回,没有参数,只有方法体,日期不通过对象或类显式调用,而是加载类时,或创建对象时隐式调用
2、基本语法
[修饰符]{
代码
}时
说明注意:
(1)修饰符只能填static或者空白
(2)有静态和非静态代码块之分
(3)逻辑语句
3、作用
(1)作为构造器的一种补充 ,构造器中有重复的东西,可以提取出来放入代码块中
(2)代码块执行速度优先于构造器
1、细节使用及注意事项
1、static代码块随着类的加载而加载,且只会执行一次
2、 类在什么时候会被调用
(1)创建对象实例时(new)
(2)创建子类对象实例,父类也会被加载。先加载父类,后加载子类
(3)使用类的静态成员(变量/方法)时
(4)类加载和普通代码块没关系,只有类的实例化才会调用普通代码块
3、静态代码块和静态属性初始化执行优先级一样,看定义的顺序
4、普通代码块和普通属性测试执行优先级一样,看定义的顺序
(1)小结
(1)static代码块是类加载时,执行,只执行一次
(2)普通代码块是在创建对象时调用的,创建一次,调用一次
5、最后调用构造器
顺序:静态>普通>构造器
6、?❗创建一个子类对象时(继承关系,C继承B,B继承A)他们的静态属性、代码块和普通属性、代码块和构造器的调用顺序
(1)父类的静态代码块、属性(按定义顺序来)
(2)子类的静态代码块、属性(按定义顺序来)
(3)父类的普通代码块、属性(按定义顺序来)
(4)父类的构造方法(构造器)
(5)子类普通代码块、属性(按定义顺序来)
(6)子类的构造方法(构造器)
7、静态代码块只能直接调用静态成员(属性、方法),普通代码块可以调用任意成员。
2、举例
eg:
class AAA{
static{
sout.("AAA静态代码块被执行");1️⃣
}
{
sout.("AAA普通代码块被执行")5️⃣
}
public int n1 =getvalue01;
public void getvalue01(){
sout.("AAA普通方法被调用")6️⃣
}
public static int n2 = getvalue02();
public static void getvalue02(){
sout.("AAA静态方法被调用") 2️⃣
}
public AAA{
//super:Object没内容
//代码块:
sout.("AAA构造器被执行")7️⃣
}
}
class BBB extend AAA{
static{
sout.("BBB静态代码块被执行");3️⃣
}
{
sout.("BBB普通代码块被执行")8️⃣
}
public BBB{
//构造器中可以看做隐藏了super和代码块
sout.("BBB构造器被执行")?
}
public int n3 =getvalue03;
public void getvalue03(){
sout.("BBB普通方法被调用")9️⃣
}
public static int n4 = getvalue04();
public static void getvalue04(){
sout.("BBB静态方法被调用")4️⃣
}
}
main(String args){
new BBB();
}
输出的是:
//先执行子父的静态属性、方法。再执行父类来说的普通属性、方法。构造器。
4.2、单例设计模式
1、设计模式:
1、大量实践后得到的代码结构、风格、思考方式。可以理解为,武功秘籍
2、单例模式---饿汉试
1、概念:采取方法保证整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法
2、步骤如下
(1)构造器私有化。//防止外类直接new 对象
(2)类的内部创建对象 //需要弄成static
(3)向往暴露一个静态公共方法 //提供一个公共的static方法 返回对象
(4)饿汉式理解:static方法随着类的加载而加载,不管有没有使用,就直接创建对象。
3、eg:
public class SingletonTest01 {
public static void main(String[] args) {
Singleton01 instance = Singleton01.getInstance(); //利用方法调用对象
Singleton01 instance01 = Singleton01.getInstance();
System.out.println(instance == instance01);
System.out.println("instance,hashCode=" + instance.hashCode());
System.out.println("instance01,hashCode=" + instance01.hashCode());
}
}
class Singleton01{
private Singleton01(){}; //私有构造器
private static Singleton01 instance = new Singleton01(); //创建对象
public static Singleton01 getInstance(){
return instance; //利用方法返回对象
}
}
// 运行结果
true
instance,hashCode=1846274136
instance01,hashCode=1846274136
3、单例模式---懒汉式
1、概念一样
2、步骤如下:
(1)设置对象为null
(2)构造器私有化 //防止外类直接new对象
(3)if判断对象是否为空,为空则创建。否则返回原来
(4)懒汉式:先进行if判断,需要对象就创建,否则就不创建。
3、eg:
4、饿汉式VS懒汉式
1、二者最主要的区别就是创建对象的时机不同:饿汉式是在类加载就创建了对象实例,懒汉式是在使用时才创建。
2、饿汉式不存在线程安全问题。懒汉式存在安全问题
3、饿汉式存在资源浪费的情况
5、final关键字
5.1、基本介绍
1、final:最后、最终的意思
2、final:可修饰类、属性、方法和局部变量。让列、属性、方法、局部变量不能被修改
1、注意事项以及细节
1、final修饰的叫常量:通常用XXX_XXX来命名
2、final修饰的属性在定义时。必须初始化值,以后不可以修改。赋值如下:
(1)定义时:final XXXX_XXX=0.08
(2)定义时:在构造器中,可以赋值。
(3)在代码块中
3、如果final修饰的属性是静态的,则初始化位置只能是2中的(1)、(2)。不能在构造器中因为构造器在创建对象才能被调用。static是要在类创建中就需要
4、final可以实例化对象(创建对象),不能继承
5、如果类不是final类,但是含有final方法,则该方法虽然不能重写,但是可以被继承(不能重写,但是可以引用)
6、如果一个类已经是final类了,就没必要将方法修饰成final方法。
7、final不能修饰构造方法(构造器)
8、final 和static 往往搭配是要弄,效率更高,不会导致类加载。因为低层做了优化
(1)理解:在类中设置了一个变量,想调用该变量,又不想让该类加载
(2)eg:
class BBB {
public static final int num =1000;
}
main(String [] args){
sout(BBB.num) //此时不会调用到BBB类
}
9、包装类和String类也是final类,不能被继承
6、抽象类
6.1、基本介绍
1、作用:父类某些方法需要声明,又不知道如何实现,可以将其声明为抽象方法,这个类就是抽象类
2、abstract:抽象
3、使用abstract关键字来修饰一个类时,这个类就是 抽象类,访问修饰符abstract类名{}
4、使用abstract关键字修饰的方法是抽象方法,抽象方法没有实体({})
5、抽象类的价值更多的作用于设计,设计好后,让子类继承并实现抽象类
6、框架和设计模式使用较多
6.2、注意事项以及细节
1、抽象类不能实例化(不能创建对象)
2、抽象类不一定要拥有抽象方法(抽象类可以没有抽象方法)。也可以拥有实现方法
3、有抽象方法,一定是一个抽象类。有抽象类不一定有抽象方法
4、abstract只能修饰方法和类
5、抽象类也是类,可以有用类的任意成员
6、抽象方法不能有实体({})
7、如果一个类继承了抽象类、则这个类必须实现抽象类的所有抽象方法,除非这个类也声明成抽象类。
8、抽象方法不能使用private、final、static来修饰
因为这三个关键字都和重写相违背。(抽象主要也是为了让子类重写)
6.3、抽象类---模板设计模式
1、概念:定义一个操作中的算法的框架, 而将一些步骤延迟到子类中。 使得子类可以不改
2、理解:父类模板方法定义不变的流程,子类重写流程中的方法
3、步骤
(1)制作一个父类的方法流程,并设置一个abstract方法
(2)子类去实现(重写)abstract方法
(3)eg:
class Animal{
sout(”动物的家“);
home();
public abstract void home();//子类继承父类需要重写的方法
}
classs Cat extends Animal{
//子类只需要重写home()方法
public void home(){
sout("房子是水泥做的");
}
}
7、接口
7.1、基本介绍
1、介绍:给出一些没有实现的方法,封装在一起,到某个类要使用的时候,根据具体状况写出来
2、语法:
(1)interface 接口名{
//属性
//方法(抽象方法、静态方法、默认实现方法)
}
(2)class 类名 implements 接口{
自己属性、方法
必须实现的接口的抽象方法
}
7.2、使用注意及细节
1、接口不能被实例化(不能创建对象)
2、接口中所有方法是public 方法,接口中抽象方法,可以不用abstract修饰(因为会默认添加public、abstract关键字)
3、一个普通类实现接口,必须实现接口中的所有方法,(可以用alt+enter快捷键)
4、抽象类去实现接口,可以不实现接口的抽象方法
5、一个类同时实现多个接口(一台电脑也有好几个usb接口)
6、接口中所有属性只能是final
而且是 public static final 修饰符
7、接口不能继承类,但接口可以继承多个接口
8、接口的修饰符只能是public和默认
7.3、接口VS继承
1、理解:接口是技能芯片,继承是拥有父类的成员,通过技能芯片就可以学会更多的东西。继承是父亲,接口是师傅。
2、小结:
(1)当子类继承了父类,就自动的拥有父类的功能
(2)如果子类需要扩展功能,可以通过实现接口的方式扩展
(3)对单继承机制的补充,继承的扩展
3、接口和继承解决的问题不同
(1)继承的价值主要在于:解决代码的复用性和可维护性
(2)接口的价值主要在于:设计,和规范
4、接口比继承灵活
(1)继承是满足:is--a的关系。(猫是动物)
(2)接口是满足:like--a的关系。(猫像鸟一样飞)。
5、接口拥有一定的解耦性
7.4、接口多态性
1、多态参数。接口引用可以指向实现了接口的类的对象(就类似于继承)
(1)理解:
interfacePL{
public void hello();
}
class AA implement PL{
public void hello(){
sout("你好啊");//重写接口中的方法
}
}
class test{
main(String[] args){
PL imp = new AA();
}
}
2、多态数组
Usb[] usbs = new Usb[2];
usbs[0] = new Phone();
interface Usb{}
class Phone implements Usb{}
3、接口存在多态传递现象
1)可以理解为C继承B,B继承A,所有C继承A

8、内部类
8.1基本介绍
1、一个类的内部又完整嵌套了另一类结构。被嵌套的类叫内部类(inner class)嵌套其他类的类称为外部类。
2、内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系
8.2、基本语法
class Outer{ //外部类
class lnner{ //内部类
}
}
class Other{ //外部其他类,它和Outer是平级关系
}
8.3、内部类的分类
1、定义在外部类局部位置上(比如,外部类中的方法上)
(1)局部内部类(有类名)
(2)匿名内部类(没有类名)❗❗❗❗❗❗
2、定义在外部类的成员(属性、方法)位置上
(1)成员内部类(没有static修饰)
(2)静态内部类(使用static修饰)
8.4、局部内部类的使用(可以理解为局部变量)
1、定义在外部类局部位置上(比如,外部类中的方法上),绝大多数在方法上。
2、局部内部类可以直接访问外部类的所有成员,包含私有的
3、不能添加访问修饰符,它的地位就是一个局部变量,局部变量不能再使用修饰符。但是!可以用final,因为局部变量也可以用final修饰。
4、作用域:仅仅定义个它的方法或代码块中
5、局部内部类可以直接访问外部类的成员
6、外部类在外部方法中,可以创建内部类对象,然后呢内部类对象.内部方法即可。
7、本质还是一个类
8、外部其他类,不能访问,局部内部类(因为局部内部类是一个局部变量)
9、如果外部类和局部内部类成员重名,遵守就近原则
(先调用内部类中的成员)。如果要访问外部类中的成员,使用外部类名.this.成员
解释(外部类名.this本质是外部类的对象,即哪个调用了装有内部类的方法,外部类.this就是哪个的对象)
8.5、匿名内部类
1、理解
(1)本质是类
(2)该类没有名字
(3)内部类
(4)同时还是一个对象
(5)定义在外部类局部位置上(比如,外部类中的方法上),绝大多数在方法上。没有类名
2、基本语法
new 类或接口(参数列表){
类体
}
3、作用
(1)简化 开发所需要创建类(匿名只能 用一次) 简化开发
4、本质:为了简化开发
(1)匿名内部类只有一次,但是对象赋值可以很多次
8.6、匿名内部类的使用细节

2、可以直接访问外部类的所有成员,包含私有的
3、作用域:方法、代码块
4、不能添加修饰符,是一个局部变量,final可以
5、外部其他类,不能访问,匿名内部类
6、如果外部类和局部内部类成员重名,遵守就近原则
(先调用内部类中的成员)。如果要访问外部类中的成员,使用外部类名.this.成员
解释(外部类名.this本质是外部类的对象,即哪个调用了装有内部类的方法,外部类.this就是哪个的对象)
8.8、成员内部类
1、说明:定义在外部类的成员位置,并没有static修饰。
2、可以直接访问外部类的所有成员,包含私有的
3、可以添加任意访问修饰符(四种),因为它的地位是一个成员
4、作用域 :外部类整个类体
5、成员内部类,访问,外部类成员(属性、方法)。直接访问
6、外部类,访问,内部类。方法:创建对象,再访问
7、外部其他类,访问,成员内部类
(1)
package classTest;
public class MemberInnerClass01 {
public static void main(String[] args) {
Outer04 outer04 = new Outer04();
outer04.say();
outer04.tt();
//外部其他类,使用成员内部类的两种方式
Outer04.Inner inner = outer04.new Inner();
inner.eat();
//方式二、在外部类中编写一个方法返回作为传递
Outer04.Inner inner1 = outer04.getInner();
inner1.eat();
}
}
class Outer04{
private int n1 =100;
public String name ="汉堡";
public Inner getInner(){
return new Inner();
}
public void say(){
System.out.println("n1="+n1+"name"+name);
}
class Inner{
int sss =10;
public void eat(){
System.out.println("吃啥啊你");
}
}
public void tt(){
Inner inner = new Inner();
inner.eat();
System.out.println(inner.sss);
}
}
8.9、静态内部类
1、可以直接访问外部类的所有静态成员,包含私有的,但是不能直接访问非静态成员
2、可以添加容易的访问修饰符
3、作用域:同其他的成员,为整个类体
4、外部类,访问,静态内部类。方法:创建对象,访问
5、 外部其他类,访问,静态内部类
(1)方法一:通过一个方法来获取一个静态内部类的对象实例,
Inner inner = Outer02.getInner02();
6、如果外部类和静态内部类成员重名,遵守就近原则
(先调用内部类中的成员)。如果要访问外部类中的成员,使用外部类名.成员
9、枚举类
一个个举例出来
9.1枚举的两种实现形式
1、自定义枚举
(1)构造器私有化
(2)本类内部创建一组对象
(3)对外暴露对象(通过为对象添加public final static 修饰符)//自动会添加
(4)可以体用get方法、不要提供set方法
2、Enum关键字实现枚举
(1)使用关键字enum来替代class
(2)public staticfinal Season SPRING = new Season(“春天”,“温暖) 直接使用SPRING (”春天“,”温暖“)替代。 解读:常量名(实参列表)
(3)如果有多个常量(对象),使用","间隔
(4)如果使用enum,要求将定义常量对象,写在前面。
9.2、enum关键字实现枚举的注意事项
1、使用enum类,会默认继承Enum类
补充:javap:反编译
2、创建常量对象时,一定要知道使用的是哪个构造器
3、创建无参构造器的对象时:MAP(); == MAP;
4、对个枚举对象,使用“,”隔开,最后一个分号结尾;
5、枚举对象必须放枚举类的首行
9.3、enum常用方法
1、name():输出枚举类的对象名
2、ordinal():输出该类枚举对象的次序、编号(从0开始)
3、 values()方法:返回所有定义枚举对象,数组形式[](反编译可以看到,平常是被隐藏了)
4、valueOf():将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报错
(1)执行过程
①输入“XXXX”,去匹配枚举对象。
②找到,返回,没找到,报错
5、compareTo():比较两个枚举常量,比较是位置(次序、编号)

6、toString():就返回枚举对象名称,如果子类重写该方法,返回子类对象属性
9.4、enum实现接口
1、使用enum关键字后,就不能再继承其他类了,因为enum隐式继承Enum。
2、枚举类和普通类一样,可以使用接口
10、注解
10.1、注解的理解
1、称为:元数据(Metdata),修饰包,类,方法,属性,构造器,局部变量
2、和注释一样,但是可以被编译运行(理解为嵌套在代码中的补充信息)
3、javaee中可配置应用程序的任何切面
10.2、基本的Annotaion介绍
1、介绍:
1、使用Annotation时,要在前面添加@符号,并把Annotation当成一个修饰符使用
2、三个基本的Annotation
1、@Override:限定某个方法,不能修饰其他类,包,属性,重写父类,注解只用于方法。最主要是语法的校验
2、@Deprecated:用于表示某个程序元素(方法、类等)过时,不推荐用,但是可以用
(1)可以修饰方法、类、字段、包、参数、等等
3、@SuppressWarning({“抑制信息all”}):抑制编译器警告
(1)有时候会出现警告,可以设置忽略
(2)有范围之分(类、方法内)
4、补充:修饰注解的注解,是元注解
10.3、JKD的元Annotation(元注解,了解)—作为了解
元注解:修饰注解的注解
1、Retention:指定注释的作用范围:SOURCE、CLASS、RUNTIME
2、Target:注释可以在哪些地方使用
3、Documented:指定该注解是否会在javadoc体现
4、INherited:子类会继承父类注释
10.4、自定义注解
1、分析
1、使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口
2、注解的参数:参数类型+参数名();
3、
