Java 面向对象之 static 关键字

static 特点
- static 是一个修饰符, 用于修饰成员
- static 修饰的成员被所有的对象所共享
- static 优先于对象存在, 因为 static 的成员随着类的加载就已经存在了
- static 修饰的成员多了一种调用方式, 即可以直接被类名所调用, 类名.静态成员
- static 修饰的数据是共享数据, 对象中存储的是特有数据.
成员变量(实例变量)与静态变量(类变量) 的区别
- 两个变量的生命周期不同
成员变量随着对象的创建而存在, 随着对象的被回收而释放
静态变量随着类的加载而存在, 随着类的消失而消失 - 调用方式不同
成员变量只能被对象调用
静态变量可以被对象调用, 还可以被类名调用 - 别名不同
成员变量也称为实例变量
静态变量也称为类变量 - 数据存储位置不同
成员变量数据存储在堆内存的对象中, 所以也叫对象的特有数据
静态变量数据存储在方法区(共享数据区)的静态区, 所以也叫对象的共享数据
静态使用注意事项
- 静态方法只能访问静态成员(包括成员变量和成员函数), 非静态方法即可以访问静态成员, 也可以访问非静态成员.
- 静态方法中不可以使用 this 或者 super 关键字.
- 主函数是静态的, 所以只能访问静态方法和静态变量.
- 静态前面省略的是类名, 非静态前面省略的是 this
备注:- 主函数是静态的, 所以只能访问静态方法和静态变量.
public Demo
{
int num = 4;
public static void main(String[] args)
{
show();
}
public void show()
{
System.out.println(num);
}
}
// 编译失败, show() 方法和成员变量 num 都是非静态的.
// 改进
public Demo
{
int num = 4;
public static void main(String[] args)
{
new Demo().show(); // 使用对象调用 show() 方法
}
public void show()
{
System.out.println(num);
}
}
2. 静态前面省略的是类名, 非静态前面省略的是 this
class Person
{
public static void main(String[] args)
{
String name;
static String country = "CN";
public void show()
{
System.out.println(country+":"+name);
// 完整写法: System.out.println(Person.country+":"+this.name);
}
}
}
主函数解析
- 格式:
public static void main(String[] args) - 主函数特殊之处
- 格式是固定的
- 被 JVM 所识别和调用
public: 因为权限必须是最大的;
static: 不需要对象, 直接用主函数所属类名调用即可
void: 主函数没有具体的返回值
main: 函数名, 不是关键字, 只是 JVM 识别的固定的名字
String[] args: 这是主函数的参数列表, 是一个数组类型的参数, 而且元素都是字符串类型
虚拟机调用主函数时, 传递了参数 new String[0].
static 内存图解

class Person
{
private String name;
private int age;
static String country = "CN";
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
public void show()
{
System.out.println(Person.country+":"+this.name+":"+this.age);
}
public static void method()
{
System.out.println(Person.country);
}
}
class StaticDemo
{
public static void main(String[] args)
{
Person.method(); // 使用类名调用静态方法
Person p = new Person("旺财",20);
p.show();
}
}
静态什么时候使用?
- 静态变量
当分析对象中所具备的成员变量的值都是相同的, 这时这个成员就可以被静态修饰.
只有数据在对象中都是不同的, 那就是对象的特有数据, 必须存储在对象中, 是非静态的.
如果是相同的数据, 对象不需要作修改, 只需要使用即可, 不需要存储在对象中, 定义成静态的. - 静态函数
函数是否用静态修饰, 就参考一点, 就是该函数功能是否有访问到对象中的特有数据.
简单点说, 从源代码看, 该功能是否需要访问非静态的成员变量, 如果需要, 该功能就是非静态的.
如果不需要, 就可以将功能定义成静态的.当然, 也可以定义成非静态的.
但是非静态方法需要被对象调用, 而创建对象仅仅是为了调用非静态的, 非静态方法没有访问特有数据, 该对象的创建是没有意义的.
class Person
{
int age;
static String country = "CN";
public void speak()
{
System.out.println("haha");
}
}
class Demo
{
public static void main(String[] args)
{
Demo d = new Demo();
d.speak(); // 调用 speak() 方法需要创建对象, 但是 speak() 方法并没有访问特有数据, 对象的创建没有意义
}
}
// 改进
class Person
{
int age;
static String country = "CN";
public static void speak() // 将方法定义为静态的
{
System.out.println("haha");
}
}
class Demo
{
public static void main(String[] args)
{
Person.speak(); //使用类名调用该方法
}
}
静态代码块
特点: 随着类的加载而执行, 而且只执行一次.
作用: 用于给类进行初始化. 如果这个类的成员全是静态的, 并不需要创建对象.
public StaticCode
{
static // 静态代码块
{
System.out.println("haha");
}
void show()
{
System.out.println("show run");
}
}
class StaticCodeDemo
{
pulic static void main(String[] args)
{
new StaticCode().show();
}
}
构造代码块
定义: 定义在类中的代码块称为构造代码块
作用: 可以给所有对象初始化
构造函数: 是给对应的对象进行针对性的初始化.
局部代码块: 限定局部变量的生存周期. 定义在方法中.
执行顺序: 静态代码块先执行, 如果有对象, 执行构造代码块,再执行构造函数. 然后执行局部代码块
class Person
{
private String name;
Person()
{
name = "baby";
System.out.println("哇哇");
}
Person(String name)
{
this.name = name;
System.out.println("哇哇");
}
public void speak()
{
System.out.println("name:" + name);
}
}
class Demo
{
public static void main(String[] args)
{
Person p1 = new Person();
Person p2 = new Person("旺财");
p1.speak();
p2.speak();
}
}
// 改进
class Person
{
private String name;
// 类中的代码块称为构造代码块. 创建对象时,调用. 可以给所有对象进行初始化
{
System.out.println("person run");
}
Person()
{
name = "baby";
cry(); // 提高复用性
}
Person(String name)
{
this.name = name;
cry(); // 提高复用性
}
pulic void cry()
{
System.out.println("哇哇");
}
public void speak()
{
System.out.println("name:" + name);
}
}
class Demo
{
// 省略...
}
//再改进
class Person
{
private String name;
// 类中的代码块称为构造代码块. 创建对象时,调用. 可以给所有对象进行初始化
{
cry();
}
Person()
{
name = "baby";
}
Person(String name)
{
this.name = name;
}
pulic void cry()
{
System.out.println("哇哇");
}
public void speak()
{
System.out.println("name:" + name);
}
}
class Demo
{
// 省略...
}
_参考资料:_
- [JavaSE 基础视频(毕向东)](https://www.bilibili.com/video/av3092180/#page=1)
Java 面向对象之 static 关键字的更多相关文章
- 131、Java面向对象之static关键字三(使用static定义方法)
01.代码如下: package TIANPAN; class Book { // 描述的是同一个出版社的信息 private String title; private double price; ...
- 130、Java面向对象之static关键字二(在没有实例化对象产生时直接操作static属性)
01.代码如下: package TIANPAN; class Book { // 描述的是同一个出版社的信息 private String title; // 普通属性 private double ...
- 129、Java面向对象之static关键字一(修改static变量)
01.代码如下: package TIANPAN; class Book { // 描述的是同一个出版社的信息 private String title; // 普通属性 private double ...
- 132、Java面向对象之static关键字四(定义一个数学的加法操作)
01.代码如下: package TIANPAN; class MyMath { // 数学操作类,类中没有属性 public static int add(int x, int y) { // 只是 ...
- 094 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 02 static关键字 04 static关键字(续)
094 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...
- 093 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 02 static关键字 03 static关键字(下)
093 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...
- 092 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 02 static关键字 02 static关键字(中)
092 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...
- 091 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 02 static关键字 01 static关键字(上)
091 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...
- Java面向对象-package import关键字
Java面向对象-package import关键字 package包关键字,在java中,有包的概念,主要是用来归类 分类作用: 便于项目的开发和维护: 这里截取随便截取一个我最近在开发的一个开源工 ...
随机推荐
- atitit.jquery tmpl模板总结 .doc
atitit.jquery tmpl模板总结 .doc 1. atitit.动态模版解析1 1.1. Jquery.tmpl.js1 1.2. 比起anrular js方便啊.1 2. 动态模板引擎解 ...
- Xcode5下使用纯代码构建简单的HelloWorld程序
转自:http://blog.csdn.net/developerxyf/article/details/12874935 新发布的Xcode5在使用模板创建工程的时候取消了以往是否要选择storyb ...
- jsp的页面包含——静态包含、动态包含
一.静态包含:包含的文件可以是jsp文件.html文件.文本文件或者一段java代码.<%@ include file="要包含的文件路径"%> 实质是先将所包含的文件 ...
- 查看linux内核和版本信息
一.查看Linux内核版本命令(2种方法): 1.cat /proc/version Linux version 3.10.0_1-0-0-8 (root@xxx) (gcc version 4.8. ...
- vs2008、vs2012添加公共头文件
当我们使用第三方库(opencv.boost)的时候,往往需要把它们的头文件和库文件添加到工程中去,然而如果每次新建工程都添加,那就太笨了,下面介绍方法可以让每个新建的工程都默认添加设置好的头文件和库 ...
- 如何查看VisualStudio的编译, 链接命令
VisualStudio默认是不显示编译命令的,如何查看呢. 对于链接器: 项目属性 -> 配置属性 -> 链接器 -> 常规 -> 显示进度 -> 设为 "/ ...
- spring读取配置文件PropertyPlaceholderConfigurer类的使用
这里主要介绍PropertyPlaceholderConfigurer这个类的使用,spring中的该类主要用来读取配置文件并将配置文件中的变量设置到上下文环境中,并进行赋值. 一.此处使用list标 ...
- C#高级学习群欢迎你(群号 128874886)
C#高级学习群,有着C# ,Asp.net ,Wpf等技术经验相当丰富的工程师,秉承着刘群主开源共享的精神,为新手和高手们提供了良好的学习交流平台,自创群以来,为群员解决了不少的技术难题,大大提高了学 ...
- linux web.py spawn-fcgi web.py 配置
本来要用uwsgi,但是...介于以前说过...这台服务器略老...redhat 3的系统...确实很老,没法用yum,没法安装很多东西,打算自己编译uwsgi,但是编译各种错误...花了快一天,最后 ...
- 列出自己常用的jdk包.
解答:JDK常用的package java.lang: 这个是系统的基础类,比如String等都是这里面的,这个package是唯一一个可以不用import就可以使用的Package java.io: ...