p374-395
类变量和类方法
类变量(静态变量)
例:
class Child{
public static Int count;//这个count可以被所有Child实例共享
/..../
}
内存中,static在堆中是独立存放的,并不在某个对象的空间中。
由于count是静态变量,于是在类加载的时候,信息放在方法区中,有些人认为count不在堆中,而是在方法区的静态域中。那到底在哪呢?
记住一点:static变量是对象共享的,不管它在哪,共识1static变量是同一个类所有对象共享,2static变量在类加载的时候就生成了。
如何访问静态变量?
同时,由于有访问修饰符,静态变量依然要遵守相关的访问权限。
如 public static int age = 10;
类变量细节讨论
1.什么时候需要使用类变量
当我们需要让某个类的所有对象都共享一个变量时,就可以考虑使用变量。
2.类变量和实例变量(普通属性)的区别
类变量是该类所有对象所共享的,而实例变量是没个对象独享的。
3.加上static就称为类变量(静态变量),否则就叫实例变量/普通变量/非静态变量。
4.类变量可以通过 类名.类变量名 或者 对象名.类变量名来访问,但jiava设计者推荐使用类名.类变量名 来访问,前提是满足访问修饰符的访问权限和范围。
5.实例不能通过类名.变量名来访问
6.类变量是在类加载的时候就初始化了, 所以我们没有创建对象实例,就能通过类名.类变量名来访问!
7.类变量的生命周期是随类的加载开始,随着类消亡而销毁。
类方法(静态方法)
访问修饰符 static 数据返回类型 方法名(){} //推荐
static 访问修饰符 数据返回类型 方法名(){}
静态方法就可以调用静态属性!静态方法可以通过类名或对象名来调用。
类方法经典的使用场景:当方法中不涉及到任何和对象相关的成员,则可以将方法设计成静态方法,提高开发效率。比如工具类的一些排序、打印特定信息等等。
类方法细节
1.类方法和普通方法都是随着类的加载而加载,将结构信息储存在方法区,类方法中无this的参数,普通方法中隐含着this的参数
2.类方法可以通过类名调用,也可以通过对象名调用。
3.普通方法和对象有关,需要通过对象名调用,比如对象名.方法名(参数),不能通过类名调用。
4.类方法中不允许使用和对象有关的关键字,比如this和super,普通方法(成员方法)可以。
5.类方法(静态方法)中,只能访问静态方法或静态变量。
6.普通成员方法,既可以访问普通变量(方法),也可以访问静态变量(方法)
小结:静态方法只能访问静态成员,非静态方法可以访问静态和非静态成员,都要遵守访问权限!
课堂练习
第一题:
count=9
count=10
11
第二题:
有错,静态的getTotalPerson方法访问了非静态的id字段
第三题:
把this.total改成Person.total就可以了。total是静态属性!用类名调用。
main方法
main的形式:
public static void main(String[ ] args){}
1.main方法是java虚拟机在调用,所以该方法的访问权限必须是public
2、java虚拟机在执行main方法时,不必创建对象,所以该方法必须是static
3.该方法接受String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数。
4.java执行的程序 参数1 参数2 参数3
0382_韩顺平Java_main语法说明_哔哩哔哩_bilibili
理解main方法
1.在main()方法中,我们可以直接调用main方法所在类的静态方法或静态属性
2.但是不能直接访问该类中的非静态成员,必须先创建本类的对象,再调用。
命令行传参数:
idea里传参数:
代码块
代码块又称为初始化块,是类的一部分,类似于方法,将逻辑语句封装在方法体中,通过{}包围起来,但是和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不能通过对象或类显式调用,而是加载类时,或创建对象时隐式调用。
基本语法
[修饰符]{
代码
};
注意:
1.修饰符可选,要写的话只能写static
2.代码块分类两类,使用static修饰的叫静态代码块,没有static修饰的叫动态代码块。
3.逻辑语句可以为任何逻辑语句(输入、输出、方法调用、循环、判断等)
4.;可以写也可以省略
代码块的好处:
1.相当于另外一种形式的构造器(对构造器的补充机制),可以做初始化的操作。
例:构造器构成重载后,若每个构造器都有相同的语句,所以可以把这些语句放在代码块中。当我们不管调用哪个构造器来创建对象,都会先调用代码块的内容。
2.提高代码的重用性
代码块使用细节(很烦人)
1.
static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次,只执行一次!如果是普通代码块,每创建一个对象,就执行一次。
2.
类什么时候被加载
1.创建对象实例时 (new)
2,创建子类对象实例,父类也会被加载
3使用类的静态成员时(静态属性,静态方法)
背下来
3
普通的代码块,在创建对象实例时,会被隐式调用,被创建一次,就会被调用一次,如果只是使用类的静态成员时,普通代码块并不会被执行。
啊,加油,今天肝到400集!好困啊
小结:static代码块是类加载的时候执行,只一次,普通代码块是创建对象的时候调用,每个对象都会调用它!
4.
创建一个对象时,在一个类调用的顺序是
1.调用静态代码块和静态属性初始化(注意,静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按照它们定义的顺序调用)
2.调用普通代码块和普通属性的初始化(优先级相同没如果有多个,那么按照他们定义的顺序初始化)
3构造器(几天不见这么拉了?)
那么,有继承的时候,是什么顺序呢?(面试爱问)
5.
构造器的最前面其实隐含了super()和 调用普通代码块,
也就是说,调用super就会去父类,按照顺序走一轮,然后回到自己的内部,调用普通代码块,然后调用
6&7.
亲测:new 子类
new孙类
按这个套路...
0389_韩顺平Java_代码块使用细节4_哔哩哔哩_bilibili
练习
第一题
in static block//调用Person类的时候会进行静态字段和静态代码块的加载,但是只在调类的时候输出这一次!
total =100
total =100
第二题:
静态成员sam初始化
static块被执行
sam1成员初始化//不要忘了普通代码块在构造器前面!!!
Test默认构造函数被调用
单例设计模式
静态方法和属性的经典应用
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱...
饿汉式
1.构造器私有化→防止用户new
2.类的内部创建对象
3.向外暴露一个静态的公共方法,如getinstance
4.代码实现
例:
package com.day18;
public class MyTool {
public static void main(String[] args) {
GirlFriend mdk = GirlFriend.getInstance();
GirlFriend xixi = GirlFriend.getInstance();
System.out.println(mdk.toString());
System.out.println(xixi.toString());
System.out.println(mdk == xixi);
}
}
class GirlFriend{
//为了能够在静态方法中返回gf对象,需要将其修饰为static,而这里static了,它只会创建一次。
private static GirlFriend gf=new GirlFriend("马大可");
private String name;
private GirlFriend(String name){
this.name= name;
}
//这个方法必须是静态的,否则就得去外面new一个!
public static GirlFriend getInstance(){
return gf;
}
@Override
public String toString() {
return "GirlFriend{" +
"name='" + name + '\'' +
'}';
}
}
这里只要加载类,就会被创建,你不一定会用它。饿汉式:你可以不用对象,但不能没有对象!
饿汉式你可能造成创建了对象,但是不使用,因此资源被浪费了。
懒汉式
1.构造器私有化,防止直接new
2.类的内部创建对象
3向外暴露一个静态的公共方法
4.代码实现
简单地说,就是你需要使用了,才创建。
package com.day18;
public class MyTool {
public static void main(String[] args) {
}
}
class GirlFriend{
private String name;
private GirlFriend(String name){//私有化构造器,不让在外面new
System.out.println("构造器被调用了");
this.name= name;
}
private static GirlFriend gf;
public static GirlFriend getInstance(){
if(gf==null){
gf = new GirlFriend("马大可");
return gf;
}
}
@Override
public String toString() {
return "GirlFriend{" +
"name='" + name + '\'' +
'}';
}
}
小结:
饿汉式问题:在类加载的时候就创建,可能存在资源浪费问题
懒汉式问题:线程安全问题
final关键字
final可以修饰类,属性,方法,局部变量
可能会用到final的情况:
1.当不希望类被继承时,可以用final修饰(结扎类?)
2.不希望被重写的方法:public final void speak(){}
3.当不希望类的某个属性被修改,public final double rare = 0.8;交80%的利息!
4.不希望局部变量被修改
final的使用细节
0394_韩顺平Java_final使用细节1_哔哩哔哩_bilibili
如果是静态的final
如果不是final类,但是含有final方法,该方法虽然不能重写,但是可以被继承