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中,有包的概念,主要是用来归类 分类作用: 便于项目的开发和维护: 这里截取随便截取一个我最近在开发的一个开源工 ...
随机推荐
- 怎样优化UITableView的性能
在iOS App中,UITableView应该是使用率最高的.同一时候也是最为复杂的视图. 差点儿全部自带的应用中都能看到它的身影,可见它的重要性. 在使用UITableView时,会常常遇到性能上的 ...
- WebApi接口安全认证——HTTP之摘要认证
摘要访问认证是一种协议规定的Web服务器用来同网页浏览器进行认证信息协商的方法.它在密码发出前,先对其应用哈希函数,这相对于HTTP基本认证发送明文而言,更安全.从技术上讲,摘要认证是使用随机数来阻止 ...
- makefile之short函数
函数名称:排序函数-$(sort LIST) 函数功能:给字串"LIST"中的单词以首字母为准进行排序(升序),并去掉重复的单词. 返回值:空格分割的没有重复单词的字串. 函数说明 ...
- locationInView和translationInView的区别
1 translationInView是UIPanGestureRecognizer下面的一个属性 locationInView则是UIGestureRecognizer下面的属性 2 tra ...
- 【网络爬虫】Httpclient4.X中使用HTTPS的方法采集12306网站
HttpClient请求https的实例: package train; import java.io.IOException; import java.security.NoSuchAlgorith ...
- 初窥XSS跨站脚本攻击
XSS跨站脚本攻击的分类 一. 反射型XSS跨站脚本攻击 二. 存储型XSS跨站脚本攻击 三. 基于DOM的XSS跨站脚本攻击 1.反射性XSS 经过后端,不经过数据库 2.储存型XSS 经过后端,经 ...
- I帧、B帧、P帧、NALU类型
i帧 i frame,即内部画面 intra picture,通常是GOP的第一个帧(即IDR)I帧是最大去除图像空间冗余信息而压缩得到的帧,自带全部信息,不参考其他帧可独立解码,称为帧内编码帧所有视 ...
- redis-3.0.6安装
此redis用来缓存跨屏账户绑定信息,安装步骤如下: ssh root@redis.td.com ,注意是root用户 tar -xzvf /nfs/install/softs/redis-3.0.4 ...
- javaweb项目配jdk
1.首先在你的本地安装jdk1.6,并将之添加至myeclipse中:window--preferences--installed jres,add添加,格式D:\program files\jd ...
- PAT007 六度空间
“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论.这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够 ...