当前位置: 首页 > news >正文

《JavaSE》---13.<面向对象系列之(附:static关键字及final关键字)>

目录

系列文章目录

前言

一、static修饰成员变量

1.1简单描述:

1.2用static修饰的好处:

1.3属于类而不属于对象

1.4如何访问更加合理:

1.5按static的修饰来分类

小结:

二、static修饰成员方法

2.1简单描述:

2.2访问静态成员方法

2.2.1代码示例:

2.2.2输出结果:

2.3在静态成员方法中不能直接调用普通成员方法

2.3.1代码示例

静态成员方法不能直接调用普通成员方法的原因

如何在静态成员方法中调用普通成员方法

代码示例:

2.3.2输出结果

2.4在普通成员方法中可以直接调用静态成员方法

2.5同理不能在静态成员方法中用this.去引用普通成员变量

代码示例:

代码示例:

小结:

三、 static修饰代码块

3.1代码块的概念及分类

3.1.1代码块的概念

3.1.1代码块的分类

3.2 ②构造块(实例代码块)

3.2.1构造块的概念

3.2.2构造块的作用与用法

3.3 ③静态代码块

3.3.1静态代码块的概念,作用,书写位置

3.3.2静态代码块的用法

3.4总结

执行顺序:

四、继承中代码的执行顺序(加上代码块)

五、static成员变量初始化

六、final关键字


系列文章目录

第一章 Java 类和对象

第二章 Java 封装

第三章 Java 继承

第四章 Java 多态

附:static关键字及final关键字

附:this和super


前言

本篇博客主要讲解Java基础语法中的

面向对象系列之

static关键字final关键字,

1.static关键字修饰成员变量、简述、好处及如何访问。

2.static关键字修饰成员方法、如何调用static修饰的成员方法。

3.static关键字修饰代码块、及代码块的概念、用法。

4.final关键字修饰基本数据类型、引用数据类型、成员变量、成员方法、类的意义。


      大家好,本人是普通一本的在校大学生一枚,目前在学习java。之前也学了一段时间,但是没有发布博客。本人现在已经大二结束了,开学就大三了,时间过的真的很快。我会利用好这个暑假,来复习之前学过的内容,并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区进行讨论!!!

      喜欢我文章的兄弟姐妹们可以点赞,收藏和评论我的文章。喜欢我的兄弟姐妹们以及也想复习一遍java知识的兄弟姐妹们可以关注我呦,我会持续更新滴,并且追求完整。
望支持!!!!!!一起加油呀!!!!

语言只是工具,不能决定你好不好找工作,决定你好不好找工作的是你的能力!!!!!

学历本科及以上就够用了!!!!!!!!!!!!!!!!!!!!!!!!!!!!


一、static修饰成员变量

1.1简单描述:

static 修饰的成员变量,称为静态成员变量 ,静态成员变量最大的特性: 不属于某个具体的对象,是所有对象所共 享的

当static修饰成员变量时,这个成员变量将不再属于对象,而是属于类。依赖于类,而不再依赖于对象,需要用类名去引用来访问到这个变量。而不再用实例化出来的对象去引用来访问。此时这个变量在类被加载的时候就被创建出来。(虽然也可以通过对象去引用,这样合法,能编译通过但是不合理,不建议这样写代码)

1.2用static修饰的好处:

当我们想要被实例化的每个对象都有一个共同的变量,存放相同的值。我们就不需要去给每个对象的这个变量去赋值。而是通过类去赋值,这样每个实例化出来的对象都可以拥有这样值。简化了我们代码的书写。

例如:

我们定义一个学生类。我们的每一个学生都在14班。此时就可以用static去修饰这个成员变量了。只需要初始化一次,而每个被实例化出来的对象都可以去用类名.去访问到这个变量。

1.3属于类而不属于对象

我们知道对象是存储在JVM中的堆区的。当被static修饰后,这样变量是存放在方法区的。此时每一个被实例化出来的对象都共用这一份被static修饰的,存放在方法区的变量。也就是说这个成员变量将不再属于对象了。而是属于这个类。

1.4如何访问更加合理:

通过类名去引用。不需要实例化对象。也可以访问。如下代码示例分析

class Stu{
//非静态成员变量/普通成员变量public String name; //学生姓名public String gender; //学生性别public short age; //学生年龄public double score; //学生分数
//静态成员变量public static int classRoom; //学生班级//成员方法public void DoClass(){System.out.println(name + "在上课");} //public void DoHomework(){System.out.println(name + "在做家庭作业");}public void Exam(){System.out.println(name + "在考试");}
}public class Test {public static void main(String[] args) {Stu.classRoom = 14;System.out.println("学生班级:"+Stu.classRoom);System.out.println("-----------------------");Stu student1 = new Stu();//new一个对象后,
//我们发现用student1也可以去访问到这个变量,但是会出现警告System.out.println("班级:"+student1.classRoom);
//这样做是可以编译通过,但是不合理。不建议这样去写代码}
}

输出结果:

学生班级:14
-----------------------
班级:14 

我们创建了一个学生类。我们假设我们要实例化的学生对象都在同一个班级14班。因此我们用static去修饰classRoom。由于用static修饰的成员变量不再属于对象。因此我们不需要再去实例化一个对象也可以访问到这个成员变量。

但是我们发现。new一个对象后,用student1去引用。虽然出现警告但也可以去访问到这个变量,
这样做是可以编译通过,但是不合理。因为这样变量是属于类的,不再属于对象,假设用对象去引用我们一般认为这样变量是属于这个对象的。显然classRoom不属于它。因此不建议这样去写代码
 Stu.classroom这样去访问。才是最合理的

1.5按static的修饰来分类

①静态成员变量:也叫做类变量。由static修饰的成员变量我们称之为静态成员变量。是属于类的,不依赖于对象,用类名去引用访问,类被加载时,这个变量就被创建出来。

②非静态成员变量:也叫做普通成员变量。没有被static修饰的成员变量我们称之为非静态成员变量。是属于对象的,用对象去引用访问。对象被实例化出来。这个变量才被创建出来。

小结:

1. static修饰的成员变量 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
2. static修饰的成员变量既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
3. static修饰的成员变量是存储在方法区当中的
4. 生命周期伴随类的一生 ( 即:随类的加载而创建,随类的卸载而销毁 )
5.static修饰的成员变量称之为静态成员变量,也叫作类变量。没有被static修饰的成员变量称作非静态成员变量,也叫做普通成员变量。

二、static修饰成员方法

2.1简单描述:

了解了用static修饰的成员变量之后,一通百通。

static修饰其他代码时也是类似的道理。用static修饰的成员方法,我们称之为静态成员方法。也叫做类方法。此时这个成员方法也将属于类而不再属于对象。类似的道理,我们用类名.去引用这个成员方法。(用对象去引用也是合法但是不合理)

我们就不再去像成员变量那样详细去解释每一个点了,因为都是类似的,我们直接看

2.2访问静态成员方法

2.2.1代码示例:

class Stu{//成员变量
//普通成员变量public String name; //学生姓名public String gender; //学生性别public short age; //学生年龄public double score; //学生分数
//静态成员变量public static int classRoom; //学生班级//成员方法//普通成员方法public void DoClass(){System.out.println(name + "在上课");} //public void DoHomework(){System.out.println(name + "在做家庭作业");}//静态成员方法public static void Exam(){System.out.println( "所有学生都在考试");}
}public class Test {public static void main(String[] args) {Stu.Exam();System.out.println("-----------------------");Stu student1 = new Stu();//new一个对象后,我们发现用student1也可以去访问到这个静态方法,但是会出现警告student1.Exam();//这样做是可以编译通过,但是不合理。不建议这样去写代码}
}

2.2.2输出结果:

所有学生都在考试
-----------------------
所有学生都在考试

类似的静态成员方法我们用类名Stu.去访问。虽然我们实例化出来的对象,也能访问到,但是不建议这样写。

 小结:

当成员方法加了static之后,调用这样方法不再需要对象去调用。而是通过类名去引用。不再依赖于对象。而不加static的方法需要我们用对象的引用才能访问到。

2.3在静态成员方法中不能直接调用普通成员方法

如下面的代码示例!

我们知道如果是非静态成员方法,我们可以直接在其中一个成员方法中去调用另一个成员方法,只需要写出对应的方法名和传入相应的参数即可。但是在静态成员方法中就不能这样直接调用普通成员方法了

2.3.1代码示例

静态成员方法不能直接调用普通成员方法的原因

 我们可以看到这样写会编译报错。因为普通成员方法是依赖对象的。而静态成员方法不依赖于对象。因此在类被加载时,静态成员变量就会被创建出来,而普通成员变量只有在类被实例化为对象时才被创建出来,因此这两者是矛盾的。当类被加载时,还没有对象被实例化时,又如何去调用那个还没有产生的普通成员方法呢!!!因此这样的写法是错误的。

如何在静态成员方法中调用普通成员方法

因为只有类被实例化后产生了对象才有了普通成员变量和方法,因此我们需要实例化一个对象,再用对象去调用,才能在静态成员方法中去调用普通成员方法。

代码示例:

class Stu{//成员变量//普通成员变量public String name; //学生姓名public String gender; //学生性别public short age; //学生年龄public double score; //学生分数//静态成员变量public static int classRoom; //学生班级//成员方法//普通成员方法public void DoClass(){System.out.println(name+"在上课");} //public void DoHomework(){System.out.println(name + "在做家庭作业");}//静态成员方法public static void Exam(){Stu student1 = new Stu();student1.name="李华";student1.DoClass();System.out.println( "所有学生都在考试");}
}public class Test {public static void main(String[] args) {Stu.Exam();}
}

2.3.2输出结果

李华在上课
所有学生都在考试

我们需要在静态成员方法中new一个对象,再用这样对象去引用这个普通的成员方法,才能成功的在静态成员方法中调用普通成员方法。

小结:

在静态成员方法不能直接调用普通成员方法,如果需要调用就必须在静态成员方法中去new一个对象。再通过当前对象的引用去调用才可以。

2.4在普通成员方法中可以直接调用静态成员方法

 这是因为在调用普通成员方法时,静态成员方法早已被创建好了,因此当然可以直接调用喽。

2.5同理不能在静态成员方法中用this.去引用普通成员变量

代码示例:

 我们看到普通成员方法中就可以用this去调用其他成员变量,而在静态方法中不能通过this去调用其他成员变量。这样原因与不能调用普通成员方法同理,普通成员变量也是依赖于当前对象的。

如果非要去引用这个成员变量,只有通过类实例化出来的对象才能去引用这个成员变量。

代码示例:

小结:

1.static修饰的成员方法,称之为静态成员方法,也称作类方法, 不属于某个具体的对象。没有被static修饰的成员方法称之为普通成员方法
2. static修饰成员方法的 可以通过对象调用,也可以通过类名. 静态方法名 (...) 方式调用,更推荐使用类名.来调用。
3.  不能在静态方法中直接访问任何非静态成员方法,如果需要访问,必须在静态方法中实例化一个对象,通过这个对象去访问。
4.  不能在静态方法中直接访问任何非静态成员变量,如果需要访问,必须在静态方法中实例化一个对象,通过这个对象去访问。
5.可以在普通成员方法中调用普通成员方法和静态成员方法。

三、 static修饰代码块

3.1代码块的概念及分类

3.1.1代码块的概念

使用 {} 定义的一段代码称为代码块

3.1.1代码块的分类

根据代码块定义的位置以及关键字,又可分为以下四种:

①普通代码块(用法非常少见不讲了)
②构造块(实例代码块)
③静态块(静态代码块)
④同步代码块(涉及多线程相关知识)

3.2 ②构造块(实例代码块)

3.2.1构造块的概念

构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块构造代码块一般用于初始化实例成员变量(普通成员变量)。

书写位置:实例代码块所处的位置在方法的外面,类的里面,与实例成员变量(普通成员变量)处于同一等级。

3.2.2构造块的作用与用法

作用:一般用来初始化普通成员变量

代码示例:

class Stu{//成员变量//普通成员变量public String name; //学生姓名public String gender; //学生性别public short age; //学生年龄public double score; //学生分数//静态成员变量public static int classRoom = 14; //学生班级//实例代码块{this.name = "李华";this.gender = "男性";this.age = 18;this.score = 100;System.out.println("实例代码块1");}//成员方法//普通成员方法public void DoClass(){Exam();//在普通成员方法中可以直接调用静态成员方法DoHomework();System.out.println(this.name+"在上课");} //public void DoHomework(){System.out.println(this.name + "在做家庭作业");}public void toShow(){System.out.println("学生姓名:" + this.name);System.out.println("学生性别:" + this.gender);System.out.println("学生年龄:" + this.age);System.out.println("学生分数:" + this.score);}//静态成员方法public static void Exam(){System.out.println("学生在考试");}
}public class Test {public static void main(String[] args) {Stu student1 = new Stu();student1.toShow();student1.DoClass();}
}

输出结果:

实例代码块1
学生姓名:李华
学生性别:男性
学生年龄:18
学生分数:100.0
学生在考试
李华在做家庭作业
李华在上课

在实例代码块中可以用this直接给实例成员变量进行赋值,来达到初始化的目的。

再者我们发现在实例代码块中我们输出了“实例代码块1”这段文字。理论上在main方法中。我们并没有调用这个实例代码块。那么这个实例代码块是何时被执行的呢?

我们将实例代码块放在类的最下面。再来输出试试

class Stu{//成员变量//普通成员变量public String name; //学生姓名public String gender; //学生性别public short age; //学生年龄public double score; //学生分数//静态成员变量public static int classRoom = 14; //学生班级//成员方法//普通成员方法public void DoClass(){Exam();//在普通成员方法中可以直接调用静态成员方法DoHomework();System.out.println(this.name+"在上课");} //public void DoHomework(){System.out.println(this.name + "在做家庭作业");}public void toShow(){System.out.println("学生姓名:" + this.name);System.out.println("学生性别:" + this.gender);System.out.println("学生年龄:" + this.age);System.out.println("学生分数:" + this.score);}//静态成员方法public static void Exam(){System.out.println("学生在考试");}//实例代码块{this.name = "李华";this.gender = "男性";this.age = 18;this.score = 100;System.out.println("实例代码块1");}
}public class Test {public static void main(String[] args) {Stu student1 = new Stu();student1.toShow();student1.DoClass();}
}

输出结果:

实例代码块1
学生姓名:李华
学生性别:男性
学生年龄:18
学生分数:100.0
学生在考试
李华在做家庭作业
李华在上课

我们发现实例代码块依然是最先被执行的。因此无关在类中实例代码块的位置,它都是最早被执行的。


3.3 ③静态代码块

3.3.1静态代码块的概念,作用,书写位置

概念:使用static定义的代码块称为静态代码块

作用:同理,静态代码块一般用于初始化静态成员变量。

书写位置:静态代码块所处的位置在方法的外面,类的里面,与静态成员变量处于同一等级。

3.3.2静态代码块的用法

在下面的代码中,不仅有静态代码块,还加了上面的实例代码块,不仅如此,我还添加了构造方法。如果又看不懂的也没有关系,你只需要看静态代码块部分就行了。

代码示例:

class Stu{//成员变量//普通成员变量public String name; //学生姓名public String gender; //学生性别public int age; //学生年龄public double score; //学生分数//静态成员变量public static int classRoom ; //学生班级//实例代码块{this.name = "李华";this.gender = "男性";this.age = 18;this.score = 100;System.out.println("实例代码块1");}//静态代码块static {classRoom = 14; //静态代码块初始化System.out.println("静态代码块1");}//构造方法public Stu(String name, String gender, int age, double score) {this.name = name;this.gender = gender;this.age = age;this.score = score;System.out.println("构造方法1");}//成员方法//普通成员方法public void DoClass(){Exam();//在普通成员方法中可以直接调用静态成员方法DoHomework();System.out.println(this.name+"在上课");} //public void DoHomework(){System.out.println(this.name + "在做家庭作业");}public void toShow(){System.out.println("学生姓名:" + this.name);System.out.println("学生性别:" + this.gender);System.out.println("学生年龄:" + this.age);System.out.println("学生分数:" + this.score);System.out.println("学生班级" + Stu.classRoom);}//静态成员方法public static void Exam(){System.out.println("学生在考试");}
}public class Test {public static void main(String[] args) {System.out.println(Stu.classRoom);Stu student1 = new Stu("LiHua","man",12,99.9);student1.toShow();System.out.println("-----------------------");Stu student2 = new Stu("ZhangWei","man",11,100);student2.toShow();}
}

输出结果:

静态代码块1
14
实例代码块1
构造方法1
学生姓名:LiHua
学生性别:man
学生年龄:12
学生分数:99.9
学生班级14
-----------------------
实例代码块1
构造方法1
学生姓名:ZhangWei
学生性别:man
学生年龄:11
学生分数:100.0
学生班级14

如果只看静态代码块的部分,我们发现,它成功的给静态变量classRoom初始化,我们还成功的打印出了这个变量。当然了,我写了这么多代码,除了静态代码块的用法,还想去总结一些别的东西。

比如我们发现,

①分割线后面并没有打印静态代码块;

②并且实例代码块new了一个新对象后,再次被执行了;

③静态代码块位于实例化代码块后面但是却比实例化代码块先执行;

④实例化代码和构造方法都对普通成员变量进行了初始化,但是打印出来的是构造方法初始化的结果。

⑤没有实例化对象依然最先打印出了静态代码块

⑥实例化对象之后才打印出了实例化代码块

这是因为(不是没写完,是在3.4的总结里一一对应了上述问题哦!)

3.4总结

1.静态代码块不管生成多少个对象,它只会执行一次。

2.实例代码块每生成一个对象,就会被执行一次。

3.静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的,比实例化代码块,构造方法执行的早。

4.实例代码块比构造方法更早执行,因此最终的值是被构造方法初始化的

5.静态代码块不依赖于对象的产生。不管有没有对象,只要有类静态代码块都会被执行

6.实例化代码块依赖于对象的产生,只有对象产生了,实例化代码块才会被执行

执行顺序:

静态代码块 > 实例代码块(构造快) > 构造方法

备注:

如果有多个静态代码块,那么就按书写的顺序执行

如果有多个实例化代码块,那么就按书写的顺序执行


四、继承中代码的执行顺序(加上代码块)

我们已经知道

① 静态代码块先执行,并且只执行一次,在类加载阶段执行

② 当有对象创建时,才会执行实例代码块,实例代码块执行完成后,最后构造方法执行

那么加上继承的关系后,又是怎样的执行顺序呢?

父类的静态代码块 > 子类的静态代码块 > 父类的实例代码块 > 父类构造方法 > 子类的实例代码块 > 子类的构造方法

注意:

第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行,静态代码块只执行一次,它用于初始化静态成员变量。因为它是依赖于类的,因此只需要执行一次就能让每个对象都拥有它的值。


五、static成员变量初始化

注意:静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性
①可以在类外,直接进行初始化赋值
②若被private修饰,可以使用Getter and Setter进行初始化
这两种初始化方式就不细说了,注意有以下两种。

5.1 就地初始化

就地初始化指的是:在定义时直接给出初始值,如下如所示。也就不详细说了,我们主要看用静态代码块进行初始化。

5.2 静态代码块初始化

在本章3.3.2我们就讲到了静态代码块初始化

六、final关键字

2.1、final修饰变量


1.final修饰普通变量

final修饰普通变量,会使这个变量变为常量,不能再被更改。

2.final修饰引用变量

final修饰引用变量,会使这个引用变量中存的地址(哈希值),不能被更改。也就是不能让它指向新的空间。如:

final int[] array1 = {1,2,3,4,5}; 不能修改array1中存的这个空间的地址(哈希值),但是可以修改这个空间里存的数据。


2.2、final修饰方法

修饰方法:表示该方法不能被重写


2.3、final修饰类

修饰类:表示此类不能被继承

我们平时是用的 String 字符串类, 就是用 final 修饰的, 不能被继承.

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • scottplot5 中 使用signalXY图,如何更新数据?
  • 数据分析中的拆解方法介绍
  • 分布式对象存储minio
  • Blender使用(二)点线面基本操作
  • Hadoop3:MR程序的数据倾斜问题处理
  • 从零开始!Jupyter Notebook的安装教程
  • 防火墙NAT智能选举综合实验
  • 【大模型】FAISS向量数据库记录:从基础搭建到实战操作
  • [C++初阶]list的模拟实现
  • 宝塔面板以www用户运行composer
  • 数仓工具—Hive基础之临时表及示例
  • SpringBoot日常:常用数据类型比较
  • C# 各版本语法新功能汇总
  • python初学之路
  • 1.33、激活可视化卷积神经网络(matalb)
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • 11111111
  • 2017 年终总结 —— 在路上
  • Apache Pulsar 2.1 重磅发布
  • C语言笔记(第一章:C语言编程)
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • php ci框架整合银盛支付
  • rabbitmq延迟消息示例
  • 仿天猫超市收藏抛物线动画工具库
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 前端js -- this指向总结。
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • 再次简单明了总结flex布局,一看就懂...
  • ​2021半年盘点,不想你错过的重磅新书
  • ​什么是bug?bug的源头在哪里?
  • #Datawhale AI夏令营第4期#AIGC文生图方向复盘
  • #微信小程序:微信小程序常见的配置传旨
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (k8s)Kubernetes 从0到1容器编排之旅
  • (笔试题)合法字符串
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (规划)24届春招和25届暑假实习路线准备规划
  • (贪心) LeetCode 45. 跳跃游戏 II
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .net dataexcel winform控件 更新 日志
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .Net Winform开发笔记(一)
  • .NET 解决重复提交问题
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .net通用权限框架B/S (三)--MODEL层(2)
  • .NET运行机制
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • /var/log/cvslog 太大
  • @Bean注解详解