文章目录

  • static关键字
    • 1.static修饰成员变量
      • 静态变量和实例变量的区别
    • 2.static修饰方法
      • 静态方法和实例方法的区别
    • 3.类的初始化顺序
    • 4.单例模式
      • 懒汉单例模式
      • 饿汉单例模式

static关键字

1.static修饰成员变量

在引入static关键字之前呢,我们先看这样一个示例:
1)设计一个Peple类如下:

public class People {//实例变量private String name;private int age;private int count;//用来统计对象的生成个数//构造方法public People(String name, int age) {this.name = name;this.age = age;count++;}//实例方法public void work() {System.out.println("好好学习,年薪百万,迎娶白富美!");}public int getCount() {return count;}
}

2)设计一个TestDemo类如下:

public class TestDemo {public static void main(String[] args) {People people1 = new People("王昭君", 18);People people2 = new People("赵云", 20);People people3 = new People("安琪拉", 19);People people4 = new People("吕布", 21);People people5 = new People("貂蝉", 20);}
}

☛在TestDemo中我们new了5个对象,调用了5次People类中的构造函数,那么count值为多少呢?因为每new一个对象,在堆上开辟一个对象,我们知道对象的内存布局分为三部分,对象头、实例变量、内存填充,在Java new 一个对象在堆上开辟的内存大小博客中有提及到,一个对象一份实例变量,所以我们虽然new了5个对象,只是在每个对象中实现了count++,count的值都为1;
☛那么怎么用count来实现统计对象的个数呢?也就是让每个对象共用一份变量?这就要引入static关键字啦!
当类中的变量用static关键字来修饰的时候,变量就变成了静态变量。静态变量是随着类的字节码的加载而被加载进内存的,所以只要程序一启动运行到该类时就会被加载进内存,不管创建了多少个对象在内存中只存储一份,跟对象无关。它是保存在方法区当中的,无论多少个对象该静态变量在内存中都只有一份。
修改上述示例中的代码,count用static关键字来修饰。
People类

public class People {//实例变量private String name;private int age;private static int count;//用来统计对象的生成个数//构造方法public People(String name, int age) {this.name = name;this.age = age;count++;}//实例方法public void work() {System.out.println("好好学习,年薪百万,迎娶白富美!");}public int getCount() {return count;}
}

静态变量是使用类名直接调用的,在以前我们设计一个类,如果把类中的实例变量设为公有或默认包访问权限的情况下,是可以通过类生成的对象来访问的;而静态变量只和类有关,可以用类名来访问(在静态变量设为公有或默认包的情况下)

静态变量和实例变量的区别

注意:静态变量是定义在类中,方法体外面的。如果你清楚JVM,应该知道局部变量是保存在栈中的,而静态变量是保存在方法区中的,局部变量出了方法就被栈回收了,而静态变量不会,所以局部变量前不能加static关键字。

2.static修饰方法

在写代码过程中,我们有没有发现有些方法是通过创建对象的方式调用的,如常见的在键盘上输入一个整数,Scanner scanner = new Scanner(System.in); scanner.nextInt();而有的方法是通过类名直接调用的,比如 Arrays.copyOf();那么什么情况下可以直接用类名调用而不用间接的通过对象呢?这就与static关键字修饰方法有关了。
看这样的一个栗子,把上述中static关键字修饰变量的示例中People类的getCount()方法设计成静态方法。
代码如下:

public class People {//实例变量private String name;private int age;public static int count;//用来统计对象的生成个数//构造方法public People(String name, int age) {this.name = name;this.age = age;count++;}//实例方法public void work() {System.out.println("好好学习,年薪百万,迎娶白富美!");}public static int getCount() {return count;}}

在TestDemo测试类中用类名调用一下getcount方法:

public class TestDemo {public static void main(String[] args) {People people1 = new People("王昭君", 18);People people2 = new People("赵云", 20);People people3 = new People("安琪拉", 19);People people4 = new People("吕布", 21);People people5 = new People("貂蝉", 20);int sum = People.getCount();System.out.println(sum);}
}

运行结果:

同时也验证了,静态变量跟对象无关,只和类有关,测试类中产生了5个对象,每产生一个对象调用一次构造函数,count++;故最后count的值为5。

静态方法和实例方法的区别

在静态方法中不可以出现实例变量,而在实例方法中可以出现实例变量,也可以出现静态变量。
因为在实例方法中有隐含的this,举个栗子,在上述People类中添加一个实例方法eat;

 public void eat() {this.name = "高富帅";count = 1;}

在实例方法中实例变量是否有this关键字都可以,因为实例方法会提供对象(this),就是指的是当前对象;当然在实例方法中也可以包含静态变量,静态变量不需要提供this,而实例方法会提供,静态变量要不要this就是它自己的事了,也就是给静态变量提供this,可以不要。
静态方法是不会提供this的,实例变量需要this,静态方法提供不了,故在静态方法中不能包含实例变量,如下:

3.类的初始化顺序

首先我们先引入静态块和实例块的概念,静态块是用来初始化静态变量的,实例块是用来初始化实例变量的。
设计一个A类如下:

public class A {//实例变量private int a;//静态变量private static int b;//静态块static {System.out.println("静态块");}//实例块{System.out.println("实例块");}//构造函数public A(){System.out.println("构造函数");}
}

为了能够在类的初始化顺序中看到实例变量和静态变量的初始化顺序,改进代码如下:

class B {public B() {System.out.println("实例变量");}
}
class C {public C() {System.out.println("静态变量");}
}
public class A {//实例变量private  B a = new B();//静态变量private static C b = new C();//静态块{System.out.println("静态块");}//实例块{System.out.println("实例块");}//构造函数public A(){System.out.println("构造函数");}
}

初始化实例变量a的时候必定会调用B类的构造函数,初始化静态变量b的时候必定会调用C类的构造函数。
在TestDemo测试类中生成A的对象,并查看运行结果。

public class TestDemo {public static void main(String[] args) {A aa = new A();}
}

运行结果:

通过运行结果可以发现,在生成对象,调用构造函数之前还搞了很多东西。
所以类的初始化的顺序 静态变量、静态块、实例变量、实例块、构造函数

4.单例模式

单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例,也就是只能产生一个对象。

懒汉单例模式

懒汉单例模式: 在第一次调用的时候实例化

1)产生对象首先需要在堆上开辟内存,然后调用构造函数来生成一个对象。如果把类的构造函数设为公有的,那么就可以随便new对象了,所以我们把构造函数设为私有的,此时把构造函数设为私有的就会产生在类外无法访问的问题,不能调用构造函数,就不能生成对象了。
2)那么就需要在类中提供一个方法,在类中生成对象,返回出去。那么问题又来了,没有生成对象,在类外怎么调用这个方法呢?这种情况下只能考虑用类名调用了,用类名调用该方法,就要把该方法设为静态方法,在该方法中调用构造函数生成对象,用一个该类的引用变量指向这个对象,但是如果把该引用变量定义在该类中,在类外多次调用该静态方法,还是会生成多个对象,所以不能把这个引用变量定义为局部变量,应该把它定义在方法外,又因为在静态方法中只能调用静态变量,所以把该变量定义为静态变量。
3)最后我们考虑,一开始该静态变量为空,调用静态方法生成对象,就会给该静态变量赋值一个地址,再次调用又会给它重新赋值新的地址,为了只能产生一个对象,我们需要在生成对象的静态方法中给定一个限定条件,当引用变量为空的时候才产生对象。
People类:

public class People {private static People p;//私有构造方法private People() {}public static People getInstance() {if (p == null) {p = new People();}return p;}
}

TestDemo类生成对象,类名调用方法。

public class TestDemo {public static void main(String[] args) {People p = People.getInstance();}
}

饿汉单例模式

饿汉单例模式: 在类初始化时,已自行实例化
饿汉单例模式与懒汉单例模式不同的是实例化时期不同,代码如下:
People类:

public class People {//私有构造方法private People() {}//已经自行实例化private static People p = new People();public static People getInstance() {return p;}
}

TestDemo类生成对象,类名调用方法。

public class TestDemo {public static void main(String[] args) {People p = People.getInstance();}
}

Java static关键字你了解多少?相关推荐

  1. Java 静态变量,静态方法,静态常量(java static 关键字)

    Java 静态变量,静态方法,静态常量  就是变量 ,方法,常量前面添加了static 关键字 为什么要使用静态的呢 有时候在处理问题时会需要两个类在同一个内存区域共享一个数据, 不如现在 Main ...

  2. java static关键字_好程序员Java教程分享static关键字的理解

    好程序员Java教程分享static关键字的理解,static关键字含义可以理解为静态的. 1. 当其修饰属性时,该属性为整个类公有,所有的对象操作的都是同一个静态属性.所以调用时应该使用类名去调用, ...

  3. java:static关键字

    static关键字主要有4种使用情况:成员变量,成员方法,代码块和内部类. 1.成员变量 虽然java中没有全局的概念,但可以通过static关键字来达到全局的效果.java类型提供了两种类型的变量, ...

  4. 关于java static 关键字

    当我们创建类时会指出哪个类的对象的外观与行为. 一般的流程是用new 创建这个类的对象,然后生成数据的存储空间,并使用相应的方法. 但以下两种情况不太适合这个流程: 只想用一个存储区域来保存一个特定的 ...

  5. [转载] Java static关键字与static{}语句块

    参考链接: Java中的静态块static block 目录直通车 一. 类的加载特性与时机 1. 类加载的特性 2. 类加载的时机 二. static的三个常用 1. 修饰成员变量 2. 修饰成员方 ...

  6. 为什么java要你写static,java static关键字理解

    文章大纲: 1.为什么static会有这样的效果? 2.static的使用 3.static误区 4.static面试题 static的魔法效果是: 被static关键字修饰的方法或者变量不需要依赖于 ...

  7. java static关键字_Java基础:static关键字作用总结

    前言 之前讲到final关键字的作用是每次面试的时候我必问求职者的两个问题之一,另外一个问题就是文本会写到的static.final和static一样,都是一个小问题可以看到一个人的基础是否扎实以及平 ...

  8. [转载] Java static关键字详解

    参考链接: Java中的static关键字 static关键字 在类中,用static声明的成员变量为静态成员变量,也成为类变量.类变量的生命周期和类相同,在整个应用程序执行期间都有效. 这里要强调一 ...

  9. java static关键字的作用是什么_static关键字有什么作用

    今天主要学习下Java语言中的static关键字. static关键字的含义及使用场景 static是Java50个关键字之一.static关键字可以用来修饰代码块表示静态代码块,修饰成员变量表示全局 ...

  10. java static关键字的作用是什么_java中的static关键字

    一.static代表着什么 在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个"伪全局"的概念,在Java中static表示"全局"或者 ...

最新文章

  1. 正则表达式中grep,sed的用法(包括基本的正则表达式和扩展的正则表达式)
  2. iOS开发网络篇—使用ASI框架进行文件下载
  3. 使用访问控制列表控制用户登录
  4. Cisco 2960 交换机密码设置
  5. RuntimeError: readexactly() called while another coroutine is already waiting for incoming data
  6. js mztreeview 双击事件_Mac下的Node.js安装教程
  7. ad9生成坐标文件_提高效率 | 教你批量提取CAD坐标的小技巧
  8. html5 删除llocalstorage变量,删除存储在浏览器中的 Local Storage 数据《 HTML5:Web 存储 》...
  9. 使用阿里云容器监控服务与第三方监控框架集成搭建自己的容器看板
  10. HNOI2015 接水果
  11. 计算机网络误区——为什么我的PING包发不出去?
  12. 关于android输入框被键盘遮挡的问题
  13. python采集人脸_python获取人脸的代码分享
  14. cs61a 2018spr hw05 的一个题目
  15. 西瓜书(机器学习周志华)公式详细推导
  16. vs2010开发activex(MFC)控件/ie插件(一)
  17. 敏感词检测软件-在线敏感词批量检测免费
  18. 采购销售价格搞错的后果及处理逻辑
  19. 交换机vlan配置实训心得_交换机与VLAN的配置实验报告.doc
  20. 【Flutter】Dart 数据类型 数字类型 ( Dart 文件创建 | num 类型 | int 类型 | double 类型 | num 相关 API )

热门文章

  1. 苹果联手中移动,谁为谁打工?
  2. 深度:行业拐点将至 “蔚来们”还有未来吗?
  3. 计算机带来科技进步,科技的进步到底带来了什么
  4. oracle认证考时间,什么时候是参加Oracle认证考试时间
  5. python中浅拷贝和深拷贝的区别_Python中浅拷贝和深拷贝的区别
  6. excel条件求和技巧:应用SUMIF函数计算客户余款
  7. 对比Excel学openpyxl系列之设置excel数字和条件格式
  8. MP4v2 Android
  9. 从理性角度看跨文化机器人的传承
  10. linux 制作本地yum源