Java关于static的作用
概述
只要是有学过Java的都一定知道static,也一定能多多少少说出一些作用和注意事项。如果已经对static了如指掌的请点击关闭按钮,看下去也只是浪费您宝贵时间而已。这篇随笔只是个人的习惯总结。
为什么需要static?
有时候我们并不想去new一个对象,只是单纯的想要调用一个函数,并且希望这个函数不会与包含它的类的其他对象有所关联。说得通俗点,即使没有创建对象,也能通过类本身来调用函数。
static静态变量
被static修饰的变量属于类变量,通过字面意思就说明了这个变量的归属(类),与之相对的是没有被static修饰的成员变量,也称为实例变量,说明这个变量是属于某个具体的对象。
public class StaticDemo
{
private static int i = 50; private int j = 60; public static void main(String[] args) {
StaticDemo staticDemo = new StaticDemo();
StaticDemo staticDemo1 = new StaticDemo();
//即使创建两个对象,也都指向同一存储空间
System.out.println(staticDemo.i);
System.out.println(staticDemo1.i);
//改变值
staticDemo.i = 52;
System.out.println(staticDemo1.i);
staticDemo.j = 65;
staticDemo1.j = 70;
System.out.println(staticDemo.j);
System.out.println(staticDemo1.j);
} }
输出
50
50
52
65
70
通过上面的实例,我们很快看出他们的区别
- 静态变量是属于类的,只有一份存储空间,是类之间共享的,牵一发而动全身,一处变,处处变。
- 实例变量属于实例对象,创建几次对象,就有几份的成员变量(拷贝)。
static修饰的静态函数
说到静态函数,就不得不提Java另一个关键词this,指的是当前的引用。意思是调用这个函数的对象,这意味着和static修饰的函数水火不容。被static修饰的函数,不能出现this关键字,否则便会报错。
去掉this,分别调用i或者j,会发现静态函数调用非静态资源时出错。这是为什么?从JVM加载机制角度来说,静态资源(被staitc修饰)是类在初始化的时候就加载的,而非静态资源是new的时候加载的。类的初始化是早于new的,加载了say()的函数时,它并不认识 j 这个成员变量,但对于非静态函数来说,当它加载时,静态资源已经加载完毕,所以它是认识 i 这个静态资源的。我们总结一下static修饰函数时的特点
- 静态函数不能引用非静态资源;
- 非静态函数可以引用静态资源;
- 静态函数可以相互调用(只要引入所在包即可);
- 静态函数没有this,因为它不依附于任何对象。
现在,我们也能知道main函数为什么必须是static的,因为程序在执行main函数时候,没有创建任何对象,只是通过类名来访问。
构造函数是不是静态函数?
《Java编程思想》提到“即使没有显示地使用static关键字,构造器实际上也是静态方法”。我至今不能确认构造器是不是静态函数,个人更偏向于不是。原因待会再阐述,先看个实例
public class StaticTest
{
private static int i; private int j; public StaticTest(int i,int j)
{
this.i = i;
this.j = j;
say1()
} public void say1()
{
System.out.println("you age is" + i);
System.out.println("you age is" + j);
} public static void main(String[] args)
{
StaticTest staticTest = new StaticTest(4,5);
StaticTest staticTest1 = new StaticTest(10,69);
System.out.println(staticTest.i);
System.out.println(staticTest.j);
System.out.println(staticTest1.i);
System.out.println(staticTest1.j); }
}
输出
you age is4
you age is5
you age is10
you age is69
10
5
10
69
实例中,确实改变了 i 的值,也符合静态资源的定义,只有一份存储空间。但构造器里用了this,与我前文所说的static属于类,不属于任何对象,this属于当前引用对象互相矛盾,并且构造函数还可以调用实例函数。一脸懵逼,这也是让我感到困惑并且认为构造函数不是静态函数的地方。如有周知,留言解惑,感谢。
静态块与非静态块
private static int i; static
{
i = 5;
}
静态块是static的重要应用之一,无函数名、作用域、返回值以及参数,静态代码块与静态变量和静态函数一样,不论类被调用多少次,该区域代码只在类初始化时第一次时执行一次,并且严格按照静态资源的定义顺序执行加载,与静态函数区别在于一个主动一个被动。
{
System.out.println("我是静态块.");
}
非静态块,同样无函数名,作用域,返回值以及参数,非静态代码块会在每次类被调用或者被实例化时执行。
实例
public class StaticTest extends Father
{
public StaticTest()
{
System.out.println("我是StaticTest的构造函数");
} {
System.out.println("我是StaticTest的非静态块");
} static
{
System.out.println("我是StaticTest的静态块");
} public static void main(String[] args)
{
new StaticTest();
new StaticTest();
}
} class Father
{
public Father()
{
System.out.println("我是Father构造函数");
} {
System.out.println("我是Father非静态块1");
} {
System.out.println("我是Father非静态块2");
} static
{
System.out.println("我是Father静态块");
} }
输出
我是Father静态块
我是StaticTest的静态块
我是Father非静态块1
我是Father非静态块2
我是Father构造函数
我是StaticTest的非静态块
我是StaticTest的构造函数
我是Father非静态块1
我是Father非静态块2
我是Father构造函数
我是StaticTest的非静态块
我是StaticTest的构造函数
加载顺序 :父类静态块 > 子类静态块 > 父类非静态块 > 父类构造函数 > 子类非静态块 > 子类构造函数
静态代码块以及非静态代码块都会在构造函数前执行,首次访问时,静态代码块会在非静态代码块前执行。
改变main函数
public static void main(String[] args)
{ }
输出
我是Father静态块
我是StaticTest的静态块
静态代码块在类加载时自动执行,非静态代码块是在创建对象时自动执行的代码,不创建对象不执行该类的非静态代码块。
静态导入
静态导入是jdk5引入的新特性,有时我们在实际应用中,并不需要整个jar包都导入,而只是想使用某部分函数。提高代码的阅读性,更好的理解程序。
import static java.lang.System.out; public class StaticTest
{
public static void main(String[] args)
{
out.println("import static测试");
System.out.println("import static测试");
}
}
输出
import static测试
import static测试
会发现,两者输出是没有区别的,但是我们少写了System. 虽然允许这么使用,但在实际开发中,我很少发现有同事这么做,主要是不利于理解,但好处是如果频繁用这个类,可以少很多的类名。
===============================================================
如发现错误,请及时留言,lz及时修改,避免误导后来者。感谢!!!
Java关于static的作用的更多相关文章
- Java 中 static 的作用
static 关键字的作用 在 Java 中 static 关键字有4种使用场景,下面分别进行介绍: 1.static 成员变量 public class Student { // 静态成员变量 pr ...
- JAVA中static什么作用?
是静态修饰符,什么叫静态修饰符呢?大家都知道,在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的,而所谓静态就是指在编译后所分配的内存会一直存在,直到程序退出内存才会释放这个空间,也就是只 ...
- Java:Java中static关键字作用
static关键字最基本的用法是: 1.被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来 2.被static修饰的方法属于类方法,可以通过类名.方法名直接引用 ...
- JAVA中static的作用
static表示"全局"."静态"的意思,用来修饰成员变量和成员方法,不过在JAVA中没有全局的意思. 1. 被static修饰的成员变量和成员方法独立于该类的 ...
- Java:static的作用分析
static表示“静态”或者“全局”的意思,但在Java中不能在所有类之外定义全局变量,只能通过在一个类中定义公用.静态的变量来实现一个全局变量. 一.静态变量 1. Java中存在两种变量,一种是s ...
- Java 静态static 关键字作用
静态的方法1.可以通过类名打点访问2.不能使用this关键字3.不能访问非静态的属性和方法 /* * 静态的方法: * 1.属于类的方法,可以通过类名打点访问 * 2.方法中不能使用this关键字 * ...
- Java中static变量作用和用法详解
static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static ...
- java中static关键字的作用
java中static关键字主要有两种作用: 第一:为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关. 第二,实现某个方法或属性与类而不是对象关联在一起 简单来说,在Java语言中,s ...
- Java之static作用的全方位总结
1.深度总结 引用一位网友的话,说的非常好,如果别人问你static的作用:如果你说静态修饰 类的属性 和 类的方法 别人认为你是合格的:如果是说 可以构成 静态代码块,那别人认为你还可以: 如果你说 ...
随机推荐
- PHP内核之旅-2.SAPI中的Cli
PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli 一.SAPI是什么? 1.1 理解SAPI (1)SAPI是PHP框架的接口层.有很多种服务器的SAPI的实 ...
- 对cordova插件配置文件plugin.xml的理解
1.配置文件表头包括了插件id,是用于唯一标识插件的.同时插件配置了一个插件名称. 2.这个文件从工作机制,也就是js代码一直到native的java插件代码工作分成两个流程.第一个流程是从代码到插件 ...
- python笔记:#003#PyCharm 的初始设置
PyCharm 的初始设置(知道) 目标 恢复 PyCharm 的初始设置 第一次启动 PyCharm 新建一个 Python 项目 设置 PyCharm 的字体显示 PyCharm 的升级以及其他 ...
- leetCode刷题(找到最长的回文字符串)
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
- 【转】IE浏览器快捷键大全
一般快捷键F11打开/关闭全屏模式 TAB循环的选择地址栏,刷新键和当前标签页 CTRL+F在当前标签页查询字或短语 CTRL+N为当前标签页打开一个新窗口 CTRL+P打印当前标签页 CTRL+A选 ...
- 双网卡+mitmproxy+iptables搭建SSL中间人(支持非HTTPS协议)
"想要解决一个问题,最根本方法的就是了解这一切是如何工作的,而不是玄学." --ASCII0X03 最近学习发现现在很多现成的安卓SSL中间人工具和教程都只针对HTTPS流量,比如 ...
- 用Java制作一个简单的图片验证码
//Java实现简单验证码功能 package project; import java.awt.Color; import java.awt.Font;import java.awt.Graphic ...
- Http协议、Tomcat、servlet
HTTP协议 Http,超文本传输协议是互联网上最广泛的一种网络协议,所有的www文件都必须遵守这个标准. Http协议由http请求和http响应组成 http请求: 1.请求行 请求方式 POST ...
- C Primer Plus 第9章 函数 编程练习
复习题: 8. int choice(int a,int b,int c){ int max; max = a; if (b > max) max = b; if (c > max) ma ...
- EOS技术研究:合约与数据库交互
智能合约操作链数据库是很常见的应用场景.EOS提供了专门的工具来做这件事(相当于Ethereum的leveldb),专业术语叫做持久化API,本文将完整严密地介绍这个工具以及对它的使用测试. 关键字: ...