🥰🥰🥰来都来了,不妨点个关注叭!
👉博客主页:欢迎各位大佬!👈
文章目录
- 1.static关键字
- 1.1 static的概念
- 1.2 static的作用
- 1.3 static的用法
- 1.3.1 static修饰成员变量
- 1.3.2 static修饰成员方法
- 1.3.3 static修饰成员变量初始化
- 2. 代码块
- 2.1 普通代码块
- 2.2 构造代码块(实例代码块、非静态代码块)
- 2.3 静态代码块
- 2.4 同步代码块
- 3. 内部类
- 3.1 实例内部类
- 3.2 静态内部类
- 3.3 局部内部类
- 3.4 匿名内部类
1.static关键字
1.1 static的概念
【概念】:static表示"全局"/"静态"的含义,但是Java语言中没有全局变量的概念,因此在Java中用static来修饰方法/变量等,称为静态成员方法/静态成员变量,也可以形成静态static代码块。
【特点】
被static修饰的成员变量/成员方法不依赖该类的任何对象,即它不依赖类特定的实例,被类的所有实例共享,静态的成员不属于对象,通过类名进行访问
【为什么】
因为只要这个类被加载,Java虚拟机可以根据类名在运行时数据区的方法区内找到它们,因此,可以在它的任何对象创建之前访问,无需引用任何对象。
【注意】
1)非静态成员变量/方法从属于对象
2)静态成员变量/方法从属于类
1.2 static的作用
现在有Student类,实例化六个对象,分别为student1 、student2、student3、student4 、student5和student6,每个对象都有自己特有的学号、性别、成绩、姓名等信息,代码如下:
public class Student {
private int sno;//学号
public String sex;//性别
public int score;//分数
public String name;//姓名
public Student(int sno, String sex, int score, String name) {
this.sno = sno;
this.sex = sex;
this.score = score;
this.name = name;
}
}
class Test {
public static void main(String[] args) {
Student student1 = new Student(1,"女",98,"张三");
Student student2 = new Student(2,"男",90,"李四");
Student student3 = new Student(3,"男",88,"小丁");
Student student4 = new Student(4,"女",99,"小万");
Student student5 = new Student(5,"女",80,"小晚");
Student student6 = new Student(6,"男",77,"小新");
}
}
假设这六名同学为同一个班的, 故他们也在同一间教室上课,如何表示?
如果在Student类中再加一个成员变量classRoom,用来保存教室,这样的方案是否可行?
在回答这些问题之前,我们先来想一想,如果这样做的话,每一个对象都会包含classRoom这一份实例变量,用这些信息来具体描述每一个学生。但是我们清楚地知道,并不需要每实例化一个对象,都保存着这个教室成员变量classRoom,这六个对象都在这个教室,需要他们来共享这个变量。在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,并不属于某个具体的对象,是所有对象所共享的。
简而言之:在不用创建对象的情况下,调用类的方法/变量,是可以共享的
1.3 static的用法
1.3.1 static修饰成员变量
在Java中,static修饰的成员变量,称为静态成员变量
【静态成员变量特性】
1)不属于某个具体的对象,是类的属性,所有对象共享,不存储在某个对象的空间中,类变量存储在方法区当中
2)可以通过类名访问,也可以通过对象访问,一般更推荐使用类名访问(毕竟都使用static啦,那就使用其特有的属性)
3)生命周期伴随类的一生,即随类的加载而创建,随类的卸载而销毁
上述问题的解决代码:
public class Student {
private int sno;//学号
public String sex;//性别
public int score;//分数
public String name;//姓名
public static String classRoom = "L1210";
}
class Test {
public static void main(String[] args) {
System.out.println(Student.classRoom);
}
}
打印结果如下:
可以清楚看到,静态成员变量并未存储到某一个对象中,存在方法区当中,供所有对象共享
1.3.2 static修饰成员方法
在Java中,被static修饰的成员方法称为静态成员方法/类方法
【静态成员方法特性】
1)不属于某个具体的对象,是类方法
2)可以通过类名访问,也可以通过对象访问,一般更推荐使用类名访问
3)对于非静态成员变量,不能在静态方法中访问任何非静态成员变量
举个例子:test1为非静态方法,age为静态变量,test1无法访问age变量
public void test1() {
static int age = 12;
}
4)对于非静态方法,静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用,即通俗记忆静态不能访问非静态,但是静态的方法内部可以访问非静态数据等,但不是能够直接使用非静态,必须依赖对象。所以这也是为什么main方法是static修饰的,既可以访问静态成员变量调用静态成员方法,也可以访问非静态成员变量调用非静态成员方法
举个例子:test2不是静态方法,test1是静态方法,所以test1不能调用test2这个非静态方法
class Test {
public static void main(String[] args) {
test2();
}
public static void test1() {
System.out.println("!!!");
}
public void test2() {
test1();
}
4)静态方法无法重写,不能用来实现多态
【总结】
1)非静态成员方法不能访问静态成员变量和调用静态成员方法
2)静态成员方法可以访问非静态成员变量和调用静态成员方法,但不是直接的,依赖于对象
1.3.3 static修饰成员变量初始化
1)直接初始化
在定义时直接给出初始值(如下面这段代码classRoom是静态成员变量,在定义时候直接初始化)
public static String classRoom = "L1210";
2)默认初始化
3)通过get和set方法进行初始化
public class Student {
private int sno;//学号
public String sex;//性别
public int score;//分数
public String name;//姓名
public static String classRoom ;
public static String getClassRoom() {
return classRoom;
}
public static void setClassRoom(String classRoom) {
Student.classRoom = classRoom;
}
}
【注意】需要在get和set方法前加static,因为classRoom是静态成员变量,只能在静态方法中访问
4)构造对象时,构造方法中赋值(不推荐使用)
public class Student {
private int sno;//学号
public String sex;//性别
public int score;//分数
public String name;//姓名
public static String classRoom ;
public Student(int sno, String sex, int score, String name, String a) {
this.sno = sno;
this.sex = sex;
this.score = score;
this.name = name;
classRoom = a;
}
}
【注意】这是构造方法,不要加任何修饰符如void之类的,可以加访问修饰限定符如public等
5)代码块初始化(使用较少)
【注意】
静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性,而静态成员变量不需要实例化对象来访问
2. 代码块
【概念】使用 {}(一对大括号) 定义的一段代码称为代码块
【分类】根据代码块定义的位置以及关键字,可分为以下四种:普通代码块、构造代码块、静态代码块和同步代码块
2.1 普通代码块
定义:方法内的代码块
2.2 构造代码块(实例代码块、非静态代码块)
定义:类内,方法外的代码块
作用:构造代码块一般用于初始化实例成员变量
public class Student {
private int sno;//学号
public String sex;//性别
public int score;//分数
public String name;//姓名
public Student(int sno, String sex, int score, String name) {
this.sno = sno;
this.sex = sex;
this.score = score;
this.name = name;
System.out.println("我是构造方法~");
}
{
System.out.println("构造代码块/实例化代码块/非静态代码块");
}
}
class Test {
public static void main(String[] args) {
Student s1 = new Student(123,"女",99,"小小");
}
}
得到结果如下:
从结果我们可以看到,先打印的构造代码块里的内容,后打印构造方法里的内容,而不是看顺序打印
可以简单认为:编译器会把静态代码块的东西放在构造方法的最前面
2.3 静态代码块
定义:使用static修饰的代码块
作用:初始化静态成员数据以及提前准备一些数据
static {
classRoom = "L1210";
System.out.println("静态代码块");
}
【注意】
1)静态代码块只执行1次,无论生成多少个对象,类被加载就执行
2)实例化代码块依赖于对象,只有实例化对象时才会执行
3)一个类中包含多个静态代码块,编译器按照定义的先后执行
2.4 同步代码块
涉及到多线程
3. 内部类
内部类定义位置与外部类成员所处的位置相同,因此称为成员内部类。
3.1 实例内部类
定义:未被static修饰的内部成员
public class Outclass {
private String a;
static int b;
int c;
public void method(){
a = "hh";
System.out.println(a);
}
// 实例内部类
class Innerclass{
int c;
public void methodInner(){
// 在实例内部类中可以直接访问外部类任意!!!外部类abc变量的修饰符都不同,任意访问!
b = 666;
method();
a = "lala";
System.out.println(a);
// 如果外部类和实例内部类中具有相同名称成员时,优先访问内部类自己的成员
c = 999;
System.out.println(c);
// 如果要访问外部类同名成员时候:外部类名称.this.同名成员名字
Outclass.this.c = 300;
System.out.println(Outclass.this.c);
}
}
public static void main(String[] args) {
System.out.println("有关实外部类的访问");
// 外部类:对象创建以及成员访问
Outclass outclass = new Outclass();
System.out.println(outclass.a);
System.out.println(Outclass.b);
System.out.println(outclass.c);
outclass.method();
System.out.println("有关实例内部类的访问");
// 1.要访问实例内部类中成员,必须要创建实例内部类的对象
// 2.创建实例内部类对象时必须借助外部类
// 3,创建实例内部类对象 依赖外部类的对象
//方法1:
Outclass.Innerclass innerClass1 = new Outclass().new Innerclass();
// 上述语法比较麻烦,也可以先将外部类对象先创建出来,然后再创建实例内部类对象
//方法2:
Outclass.Innerclass innerclass2 = outclass.new Innerclass();
innerclass2.methodInner();
}
}
【注意】
1)在实例内部类方法中可以直接访问外部类中的任何成员
2)外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。
3)实例内部类受public、private等访问限定符的约束
4)在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,需要:
外部类名称.this.同名成员 来访问
5)实例内部类对象必须在先有外部类对象前提下才能创建
6)实例内部类的非静态方法中包含一个指向外部类对象的引用
3.2 静态内部类
定义:被static修饰的内部成员
public class Outclass {
private String a;
static int b;
int c;
public void method1(){
a = "hh";
System.out.println(a);
}
public static void method2(){
System.out.println(b);
}
// 静态内部类
static class Innerclass{
int c;
public void methodInner(){
// a = "lala";
// c = 20;
//编译失败 静态内部类中只能访问外部类的静态成员变量 a、b变量不是静态变量
b = 100; //b可以访问,因为b被static修饰,是静态变量
//method1();
//编译失败 静态内部类中只能访问外部类的静态成员方法 method1不是静态方法
method2();
}
}
public static void main(String[] args) {
//直接用外部类
Outclass.Innerclass innerClass = new Outclass.Innerclass();
innerClass.methodInner();
}
}
【注意】
1)静态内部类中只能访问外部类中的静态成员
2)创建静态内部类对象时,不需要先创建外部类对象,因为静态不依赖对象
3.3 局部内部类
定义:外部类的方法体或者{}
局部内部类只能在其定义的位置使用,一般使用非常少
public class Outclass {
public String a;
// 局部内部类(在这个方法体中)
public void method() {
class Innerclass {
public void methodInner() {
System.out.println(a);
}
}
Innerclass innerclass = new Innerclass();
innerclass.methodInner();
}
}
【注意】
1) 局部内部类只能在所定义的方法体内部使用
2)不能被修饰符修饰,如public、static等修饰符
3.4 匿名内部类
涉及到抽象类和接口
本期内容回顾~
下期再见!一起加油呀~