10.1类变量(静态变量)类方法
10.2类变量的内存布局
10.3如何访问类变量
10.4类变量使用注意事项和细节讨论
10.5 类方法(static静态方法)
10.6类方法的使用场景
10.7 类方法使用细节
10.8深入理解mian方法(public static void main(String [] args){}
10.9 代码块
10.10代码块注意事项
10.11代码块的用处及案例演示
3、案例演示
10.12代码块的注意事项和使用细节
2.类什么时候被加载呢?(重点)
10.13创建对象时,在一个类中的调用顺序(重点)
10.14 创建一个子类对象时,他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下
这里需要注意的是static变量的位置跟jdk的版本有关,有的说是在方法区有的说是在静态域。
不管她在哪我们需要记住以下两点
1、static变量是同一个类所有对象共享
2、static类变量在类加载的时候就生成了
1、访问类变量:类名.类变量名 or 对象名.类变量名
2、注意:静态变量的访问修饰符和访问范围权限和普通变量是一样的
当我们需要让某个类的所有对象共用一个变量时,可以将该变量设置成静态变量
2、加上static 称为类变量或者静态变量否则称为 普通变量/实例变量/非静态变量
3、访问类变量:类名.类变量名 or 对象名.类变量名(java设计者推荐我们使用类名.类变量名)
4、类变量在类加载时就初始化了,就是说即使没有创建对象,只要类加载了就可以使用类变量
public static void infor(){} //访问修饰符 static 数据返回类型 方法名(){}
1、当方法中不涉及任何和对象相关的成员,则可以将方法设计成静态方法,提高开发效率
类方法(静态方法)只能调用静态成员(静态属性、静态方法)
普通方法既可以调用静态成员(静态属性、静态方法)也可以调用普通成员(普通属性、普通方法)
1.基本介绍:代码块属于类中的成员(是类的一部分)类似于方法,将逻辑语言封装到方法体中,通过{}包围起来。
2、和方法不同,没有方法名,没有返回,没有参数,只有方法体,并且不用通过对象调用,而是在类加载的时候或者创建对象时隐式调用。
3、语法 修饰符{
代码
}
1、修饰符要是写的话只能写static
2、代码块分为两类,使用static修饰的代码块,叫做静态代码块,否则称为普通代码块
3、代码块中的逻辑语句可以为任意的逻辑语句
5、;可以写,也可以省略
1、我的理解:代码块相当于另一种形式的构造器(对构造器的补充机制),可以做初始化的操作
2、使用场景:如果多个构造器中都含有重复的语句,可以抽取到初始代码块中,提高代码的重用性
package com.cds.block;
public class Test01 {
public static void main(String[] args) {
Movie movie = new Movie("泰坦尼克号");
System.out.println("================================");
Movie movie1 = new Movie("泰坦尼克号",39);
System.out.println("================================");
Movie movie2 = new Movie("泰坦尼克号",39,"jack");
}
}
class Movie{
private String name;
private double price;
private String director;
{
System.out.println("电影屏幕打开...");
System.out.println("广告开始...");
System.out.println("电影正是开始...");
}
/*
* (1) 下面的三个构造器都有相同的语句
* (2)这样代码看起来比较冗余
* (3) 这时我们可以把相同的语句,放入到一个代码块中,即可
*(4) 这样当我们不管调用哪个构造器,创建对象,都会先调用代码块的内容
* (5)代码块调用的顺序优先于构造器.
*/
public Movie(String name) {
// System.out.println("电影屏幕打开...");
// System.out.println("广告开始...");
// System.out.println("电影正是开始...");
this.name = name;
}
public Movie(String name, double price) {
// System.out.println("电影屏幕打开...");
// System.out.println("广告开始...");
// System.out.println("电影正是开始...");
this.name = name;
this.price = price;
}
public Movie(String name, double price, String director) {
// System.out.println("电影屏幕打开...");
// System.out.println("广告开始...");
// System.out.println("电影正是开始...");
this.name = name;
this.price = price;
this.director = director;
}
}
1、static代码块也叫静态代码块,静态代码块时随着类的加载被执行,且只会执行一次,而普通代码块 每创建一个对象就被调用
案例演示
//创建对象实例时(new),静态代码块和普通代码块都执行,且静态优先,因为先加载类
//使用类的静态成员时(静态属性,静态方法),类加载,静态代码块执行
//当创建子类对象时,先调用父类的静态代码块,再子类静态代码块,再父类普通代码块,再子类普通代码块。
源码:
package com.cds.block;
/*
* 1、static代码块也叫静态代码块,静态代码块时随着类的加载被执行,
* 且只会执行一次,而普通代码块 每创建一个对象就被调用
2.类什么时候被加载呢?(重点)
创建对象实例时(new)
创建子类对象实例时,父类也会被加载
使用类的静态成员时(静态属性,静态方法)*/
public class Test02 {
public static void main(String[] args) {
// System.out.println(A.age);//使用类的静态成员时(静态属性,静态方法),类加载
// A a = new A();//创建对象实例时(new),静态代码块和普通代码块都执行,且静态优先,因为先加载类
B b = new B();
}
}
class A{
public static int age = 100;
public static void say(){
System.out.println("A类中say()静态方法执行");
}
static {
System.out.println("A类的静态代码块执行");
}
{
System.out.println("A类的普通代码块被执行");
}
}
class B extends A{
static {
System.out.println("B类的静态代码块执行");
}
{
System.out.println("B类的普通代码块被执行");
}
}
(1)调用静态代码块和静态属性初始化(注意静态代码块和静态属性的优先级是一样的如果有多个静态代码块和静态属性则按照他们的顺序执行)
(2)调用普通代码块和普通属性(注意普通代码块和普通属性的优先级是一样的如果有多个普通代码块和普通属性则按照他们的顺序执行)
案例演示
源码:
package com.cds.block;
/*
* (1)调用静态代码块和静态属性初始化
* (注意静态代码块和静态属性的优先级是一样的
* 如果有多个静态代码块和静态属性则按照他们的顺序执行)
(2)调用普通代码块和普通属性
* (注意普通代码块和普通属性的优先级是一样的
* 如果有多个普通代码块和普通属性则按照他们的顺序执行)*/
public class Test03 {
public static void main(String[] args) {
AA aa = new AA(19);
}
}
class AA{
private static int age = getAge();
static {
System.out.println("AA类中静态代码块被执行");
}
public static int getAge(){
System.out.println("AA类中getAge()被调用,静态变量初始化");
return 100;
}
public AA(int age) {
System.out.println("AA类中构造器被调用");
this.age = 10;
}
public static void say(){
System.out.println("AA类中静态方法say()被执行");
}
public void hello(){
System.out.println("AA类中普通方法hello()被执行");
}
private int n2 = getN2();
public int getN2(){
System.out.println("AA类中getN2()被调用,普通变量初始化");
return 200;
}
{
System.out.println("AA类中普通代码块被执行");
}
}
class BB {
}
(3)构造器 的前面 其实是隐藏了(1) super()和(2)调用普通代码块,!!!!重要
就是·静态代码块是加载类时直接执行,然后普通代码块在创建对象时,是在构造器中隐藏的super()后面执行的。
静态相关的·代码块,属性初始化,在类加载时,就执行完毕,因此是优先于构造器和普通代码块和普通代码块执行的
案例演示:
源码:
package com.cds.block;
/*
* 构造器 的前面 其实是隐藏了 super()和调用普通代码块,
* 静态相关的·代码块,属性初始化,在类加载时,就执行完毕,
* 因此是优先于构造器和普通代码块和普通代码块执行的*/
public class Test04 {
public static void main(String[] args) {
BBB bbb = new BBB();
}
}
class AAA{
{
System.out.println("AAA的普通代码块被调用");
}
public AAA() {
System.out.println("AAA的构造器被调用");
}
}
class BBB extends AAA{
{
System.out.println("BBB的普通代码块被调用");
}
public BBB() {
//这里有隐藏的执行要求
//(1)super()
//(2)调用普通代码块
System.out.println("BBB的构造器被调用");
}
}
注意:静态代码块只能直接调用静态成员(静态 属性和静态方法),普通代码块可以调用任意成员。
源码:
package com.cds.block;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
/*
* (1)调用静态代码块和静态属性初始化
* (注意静态代码块和静态属性的优先级是一样的
* 如果有多个静态代码块和静态属性则按照他们的顺序执行)
(2)调用普通代码块和普通属性
* (注意普通代码块和普通属性的优先级是一样的
* 如果有多个普通代码块和普通属性则按照他们的顺序执行)*/
public class Test03 {
public static void main(String[] args) {
BB bb = new BB(18);
}
}
class AA{
private static int age = getAge();
static {
System.out.println("AA类中静态代码块被执行");
System.out.println(AA.age);//静态代码块里面只能调用静态成员
AA.say();//静态代码块里面只能调用静态成员
// AA.n2;//静态代码块里面不能调用普通成员
}
public static int getAge(){
System.out.println("AA类中getAge()被调用,静态变量初始化");
return 100;
}
public AA(int age) {//构造器
System.out.println("AA类中构造器被调用");
this.age = 10;
}
public static void say(){
System.out.println("AA类中静态方法say()被执行");
}
public void hello(){
System.out.println("AA类中普通方法hello()被执行");
}
private int n2 = getN2();
public int getN2(){
System.out.println("AA类中getN2()被调用,普通变量初始化");
return 200;
}
{
System.out.println("AA类中普通代码块被执行");
}
}
class BB extends AA{
private static int num1 = getNum1();
private int num2 = getNum2();
public int getNum2() {
System.out.println("BB类的普通属性初始化");
return 400;
}
public static int getNum1() {
System.out.println("BB类的静态属性初始化");
return 300;
}
static {
System.out.println("BB类的静态代码块被调用");
}
{
System.out.println("BB类的普通代码块被执行");
}
public BB(int age) {
super(age);
System.out.println("BB类的构造器被执行");
}
}
好啦,上篇就到这里了~
马上更新下篇哦。