staitc
一、static和非static变量
1. static 修饰的变量称为类变量或全局变量或成员变量,在类被加载的时候成员变量即被初始化,与类关联,只要类存在,static变量就存在。非static修饰的成员变量是在对象new出来的时候划分存储空间,是与具体的对象绑定的,该成员变量仅为当前对象所拥有的。
2. static修饰的变量在加载的时候先于main方法加载在内存中的数据共享区-------方法区,而非static的变量在加载的时候,是要创建变量才加载在堆内存中的。
3. 一个static变量单独划分一块存储空间,不与具体的对象绑定在一起,该存储空间被类的各个对象所共享。static变量值在方法区加载一次,而非static在创建对象时会加载很多次。每次创建都会拷贝一份。
4. 对象在引用成员变量是直接通过类名.变量名调用,对象在引用实例变量时只能通过对象名.变量名调用。
5. 在类中调用成员变量时直接调用或者以类名.变量名方式调用,实例变量则用this或者直接调用。
public class Main {
static int value = 33;
public static void main(String[] args) throws Exception{
new Main().printValue();
}
private void printValue(){
int value = 3;
System.out.println(this.value);
}
}
这里面主要考察队this和static的理解。this代表什么?this代表当前对象,那么通过new Main()来调用printValue的话,当前对象就是通过new Main()生成的对象。而static变量是被对象所享有的,因此在printValue中的this.value的值毫无疑问是33。在printValue方法内部的value是局部变量,根本不可能与this关联,所以输出结果是33。在这里永远要记住一点:静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。
二、static方法和非static方法
1. static修饰的方法也和static一样。先于main方法被加载到方法区,以便共享使用。
2. 静态的static方法中不能使用this或者super关键字,因为static方法是先于对象创建之前就已经加载的方法,是属于类的方法,而this和super指向的是本类的对象或者父类的对象,非静态的方法是属于对象的,方法里可以用this和super。
3. static方法可以用对象.方法名来调用,也可以用类名.方法名来调用。而非静态的方法只能创建对象后时调用。
4. static方法是加载一次,被所有的对象所共享。而非静态方法是有多少个对象就拷贝多少次,每个对象只能调用自己的拷贝的方法。
5. 对象调用非静态的方法时,不考虑线程安全性的问题,而调用静态方法时,要考虑安全性的问题。因为静态方法只有一份。而对象的方法是自己有自己的。
6. 同一个类中,静态方法中只能访问类中的静态成员。而非静态方法可以访问静态或非静态的方法(使用类名调用,或者创创建本类的对象调用)。
三、static静态代码块
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。
四、static加载顺序DEMO
Demo1
public class Test extends Base{
static{
System.out.println("test static");
}
public Test(){
System.out.println("test constructor");
}
public static void main(String[] args) {
new Test();
}
}
class Base{
static{
System.out.println("base static");
}
public Base(){
System.out.println("base constructor");
}
}
base static
test static
base constructor
test constructor
输出如上,这段代码具体的执行过程,在执行开始,先要寻找到main方法,因为main方法是程序的入口,但是在执行main方法之前,必须先加载Test类,而在加载Test类的时候发现Test类继承自Base类,因此会转去先加载Base类,在加载Base类的时候,发现有static块,便执行了static块。在Base类加载完成之后,便继续加载Test类,然后发现Test类中也有static块,便执行static块。在加载完所需的类之后,便开始执行main方法。在main方法中执行new Test()的时候会先调用父类的构造器,然后再调用自身的构造器。
Demo2
public class Test {
Person person = new Person("Test");
static{
System.out.println("test static");
}
public Test() {
System.out.println("test constructor");
}
public static void main(String[] args) {
new MyClass();
}
}
class Person{
static{
System.out.println("person static");
}
public Person(String str) {
System.out.println("person "+str);
}
}
class MyClass extends Test {
Person person = new Person("MyClass");
static{
System.out.println("myclass static");
}
public MyClass() {
System.out.println("myclass constructor");
}
}
test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor
输出如上,这段代码的具体执行过程。首先加载Test类,因此会执行Test类中的static块。接着执行new MyClass(),而MyClass类还没有被加载,因此需要加载MyClass类。在加载MyClass类的时候,发现MyClass类继承自Test类,但是由于Test类已经被加载了,所以只需要加载MyClass类,那么就会执行MyClass类的中的static块。在加载完之后,就通过构造器来生成对象。而在生成对象的时候,必须先初始化父类的成员变量,因此会执行Test中的Person person = new Person(),而Person类还没有被加载过,因此会先加载Person类并执行Person类中的static块,接着执行父类的构造器,完成了父类的初始化,然后就来初始化自身了,因此会接着执行MyClass中的Person person = new Person(),最后执行MyClass的构造器。
参考:https://www.cnblogs.com/dolphin0520/p/3799052.html
https://blog.csdn.net/a907691592/article/details/51668440
staitc的更多相关文章
- vue中的项目目录assets和staitc的区别
vue中的项目目录assets和staitc的区别 在进行发行正式版时,即为npm run build编译后, assets下的文件如(js.css)都会在dist文件夹下面的项目目录分别合并到一个文 ...
- java中普通的顶级类是不能使用static关键字修饰的。只有内部类可以使用static修饰,也可以不使用staitc关键字修饰。
java中普通的顶级类是不能使用static关键字修饰的.只有内部类可以使用static修饰,也可以不使用staitc关键字修饰. java中的类可以是static吗?答案是可以.在java中我们可以 ...
- 详解java中staitc关键字
一.static定义 static是静态修饰符意思,什么叫静态修饰符呢?大家都知道,在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的,而所谓静态就是指在编译后所分配的内存会一直存在,直到 ...
- 浅析Java 泛型
泛型是JavaSE5引入的一个新概念,但是这个概念在编程语言中却是很普遍的一个概念.下面,根据以下内容,我们总结下在Java中使用泛型. 泛型使用的意义 什么是泛型 泛型类 泛型方法 泛型接口 泛型擦 ...
- [C#6] 1-using static
0. 目录 C#6 新增特性目录 1. 老版本的代码 1 using System; 2 3 namespace csharp6 4 { 5 internal class Program 6 { 7 ...
- java内存溢出和内存泄露
虽然jvm可以通过GC自动回收无用的内存,但是代码不好的话仍然存在内存溢出的风险. 最近在网上搜集了一些资料,现整理如下: —————————————————————————————————————— ...
- CSS篇之DIV+CSS布局
<div></div> div与其他标签一样,也是一个XHTML所支持的标签. div是XHTML中指定的,远门用于布局设计的容器标记. 简单的CSS布局 头部 内容 页脚 & ...
- Java static 的一两点使用
这篇文章是关于Java static关键字的使用,主要会介绍以下的内容: static 的概念 static的各种应用 总结 static 是什么 static 顾名思义是静态的意思.与this相对, ...
- Java提高篇——静态代码块、构造代码块、构造函数以及Java类初始化顺序
静态代码块:用staitc声明,jvm加载类时执行,仅执行一次构造代码块:类中直接用{}定义,每一次创建对象时执行.执行顺序优先级:静态块,main(),构造块,构造方法. 构造函数 public H ...
随机推荐
- springIOC源码分析(BeanFactroy)
启动spring容器加载bean的方式有两种:最基本的容器BeanFactory和高级容器ApplicationContext.这篇文章介绍使用BeanFactory加载bean时的整个过程,当然,A ...
- NOIP2016提高组复赛C 愤怒的小鸟
题目链接:http://uoj.ac/problem/265 题目大意: 太长了不想概括... 分析: 状压DP的模板题,把所有可能的抛物线用二进制表示,然后暴力枚举所有组合,详情见代码内注释 代码如 ...
- java学习之—递归实现二分查找法
/** * 递归实现二分查找法 * Create by Administrator * 2018/6/21 0021 * 上午 11:25 **/ class OrdArray{ private lo ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
今天服务器遇到了一个很熟悉的问题, 输入 #mysql -u root -p ERROR 2002 (HY000):Can't connect to local MySQL server ...
- 表单中input name属性有无[]的区别
1 input数组 如下一个表单: <input type="text" name="username[]" value="Jason" ...
- Linux 下 解压zip文件出现乱码
网上下载了一个文件,鼠标右键提取出来发现中文文件名全部乱码: 打开命令行 unzip -h 可以看到 -O 参数 制定编码解压: 比如: unzip -O CP936 xxx.zip
- Spring 使用介绍(二)—— IoC
一.简单使用:Hello World实例 1.maven添加依赖 <dependency> <groupId>org.springframework</groupId&g ...
- shiro注解和标签
Controller中注解: @RequiresAuthentication @RequiresGuest @RequiresPermissions("account:create" ...
- 1、linux下对绝对路径和相对路径
cd / 回到根目录 cd /etc 回到根目录下的etc 目录下 绝对路径 路径写法是从根目录/ 写起来的. cd . 当前目录 cd .. 上层目录 cd ~回到自家的根目 ...
- Educational Codeforces Round 60 Div. 2
F:考虑对于每个字母对求出删掉哪些字符集会造成字符串不合法,只要考虑相邻出现的该字母对即可,显然这可以在O(np2)(或小常数O(np3))内求出.然后再对每个字符集判断是否能通过一步删除转移而来即可 ...