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中,有包的概念,主要是用来归类 分类作用: 便于项目的开发和维护: 这里截取随便截取一个我最近在开发的一个开源工 ...
随机推荐
- SCUT个人整理的常见问题
1.刚打开redis和服务端,测试时发现明显延时 刚开始会同步数据比较卡,需要进行一次操作才会同步.这个问题暂时没去研究 2.Server failed to start error:The mode ...
- maven添加额外archetype
用Eclipse + m2e 插件新建maven项目时发现archetype太少了,网上搜索如何添加额外的archetype. http://maven.apache.org/archetype/ma ...
- (WPF)依赖属性
属性触发器: <Button MinWidth=" 75" Margin="10"> <Button.Style> <Style ...
- android studio - 修改logcat颜色字体
修改logcat 颜色 (1) 在Android Studio 菜单栏 打开 Preferences -> Editer -> Colors & Fonts -> Andr ...
- 简单讲一下 SpringMVC的执行流程?
执行流程: 1. 用户向服务器发送请求,请求被 Spring 前端控制 Servelt DispatcherServlet 捕获(捕获) . DispatcherServlet对请求 URL进行解析 ...
- Github上Fork代码,及源码修改
iOS开发中经常遇到这种情况,你使用的第三方库不能完全满足自己项目需要,只能修改源码来解决. 我们以前的解决办法是,添加到项目中直接修改源码.这样就有一个问题,不能和源库同步,当作者更新后你不能(po ...
- 设置Tomcat编码(UTF-8)
Tomcat的默认编码是ISO-8859-1,如果有是get请求时,会出现乱码,这种情况可以修改Tomcat的编码解决. 在tomcat的conf目录下,编辑server.xml配置文件,在Conne ...
- 如何在openwrt上实现 U盘的自动挂载
U盘的自动挂载,分为两种场景 1.路由器先上电,然后插上U盘并自动挂载 2.路由器先插上U盘,然后上电并自动挂载 上述场景的实现,需要如下几个步骤: 1.支持如下模块: USB驱动模块:USB OHC ...
- 我不会OOO,仍然可以XXX_转
转自:http://blog.csdn.net/absurd 按照<审死官>里的读法,标题可以读着:答复:我不会圈圈圈,仍然可以叉叉叉.圈圈叉叉并不特指某个东西,而是一个通配符.代表诸如: ...
- Swift基础--ijkplayer编译
这篇与Swift基本上没有什么关系,只是之后会用到,这次编译是使用Mac编译IOS版本号的.以下是编译流程,最后是整个项目的下载地址.由于下载太慢了. 1.下载源代码 git clone https: ...