-
2021-08-16 14:37:24
static关键字主要有两种作用:
第一,为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。
第二,实现某个方法或属性与类而不是对象关联在一起
具体而言,在Java语言中,static主要有4中使用情况:成员变量、成员方法、代码块和内部类
(1)static成员变量:
Java类提供了两种类型的变量:用static关键字修饰的静态变量和不用static关键字修饰的实例变量。静态变量属于类,在内存中只有一个复制,只要静态变量所在的类被加载,这个静态变量就会被分配空间,因此就可以被使用了。对静态变量的引用有两种方式,分别是“类.静态变量"和”对象.静态变量"
实例变量属于对象,只有对象被创建后,实例变量才会被分配内存空间,才能被使用,它在内存中存在多个复制,只有用“对象.实例变量”的方式来引用。
(2)static成员方法:
Java中提供了static方法和非static方法。static方法是类的方法,不需要创建对象就可以被调用,而非static方法是对象的方法,只有对象被创建出来后才可以被使用
static方法中不能使用this和super关键字,不能调用非static方法,只能访问所属类的静态成员变量和成员方法,因为当static方法被调用时,这个类的对象可能还没被创建,即使已经被创建了,也无法确定调用哪个对象的方法。同理,static方法也不能访问非static类型的变量。
单例设计模式:
static一个很重要的用途就是实现单例设计模式。单利模式的特点是该类只能有一个实例,为了实现这一功能,必须隐藏类的构造函数,即把构造函数声明为private,并提供一个创建对象的方法,由于构造对象被声明为private,外界无法直接创建这个类型的对象,只能通过该类提供的方法来获取类的对象,要达到这样的目的只能把创建对象的方法声明为static,程序实例如下:
class Singleton{
private static Singleton instance=null;
private Singleton(){}
public static Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}(3)static代码块
static代码块在类中是独立于成员变量和成员函数的代码块的。注意:这些static代码块只会被执行一次
(4)static与final结合使用表示的意思:
对于变量,若使用static final修饰,表示一旦赋值不能修改,并且通过类名可以访问。
对于方法,若使用static final修饰,表示该方法不可被覆盖,并且可以通过类名直接访问。
public class Test{
public static int testStatic(){ static final int i=0; System.out.println(i++); } public static void main(String[] args){ Test test=new Test(); test.testStatic(); }
}
上述程序运行的结果:编译失败.
在Java语言中,不能在成员函数内部定义static变量.更多相关内容 -
关于java中的static关键字
2022-03-17 21:34:241.static 英文译名为静态的; 2.static修饰的方法为静态方法; 3.static修饰的变量为静态变量; 4.所有static修饰的元素均为静态的,都可以用...——java中static关键字的用法: 实例变量(对象变量)每个jav...关于java中的static关键字;
1.static 英文译名为静态的;
2.static修饰的方法为静态方法;
3.static修饰的变量为静态变量;
4.所有static修饰的元素均为静态的,都可以用类名.的方法进行调用【其实用引用.的方式进 行调用也是可以的,不会报错,但会有警告,因此不建议使用引用.的方式进行调用;
5.static修饰的都是类级别的特征和具体的对象无关;
——java中static关键字的用法:
实例变量(对象变量)每个java对象就有一份,那么100个对象就有100份!这里有什么缺点?
例:
public class Chinese {
String id;//实例变量
String name;//实例变量
String country;//实例变量public Chinese(String id,String name,String country) { //构造方法,形参列表传递实参
this.id=id;
this.name=name;
this.country=country;
}
}public class ChineseTest01 {
public static void main(String[] args) { //main方法为程序的入口,程序由此处进行
Chinese zhangshan=new Chinese("1","张三","中国"); //new调用构造的方法
Chinese lishi=new Chinese("2","李四","中国"); //new调用构造的方法
System.out.println(zhangshan.id+","+zhangshan.name+","+zhangshan.country);
System.out.println(lishi.id+","+lishi.name+","+lishi.country);
}}
运行截屏:
—— 以上每个实例变量都储存在对象中,都需要在堆内存中开辟内存;在以上的代码以及代码截屏中,张三和李四都有中国国籍,并且国籍都为中国,将country定义为实例变量浪费空间,没必要让每个对象内都保留国籍信息,因此可以在country的前面,将其变成类级别的变量,通过类访问。
以上代码加上static静态关键字效果如下:
public class Chinese {
String id;//实例变量
String name;//实例变量
static String country="中国";//实例变量
public Chinese(String id,String name) {
this.id=id;
this.name=name;
}
}public class ChineseTest01 {
public static void main(String[] args) {
Chinese zhangshan=new Chinese("1","张三");
Chinese lishi=new Chinese("2","李四");
System.out.println(zhangshan.id+","+zhangshan.name+","+Chinese.country);
System.out.println(lishi.id+","+lishi.name+","+Chinese.country);
}}
运行截屏:
这样就节省了堆内存的空间!
另加说明:
—— static String country;中的country为静态变量,静态变量在类加载的时候不需要创建对象内存就开放了
——静态变量储存在方法区内存中
什么时候成员变量声明为实例变量?
—所有对象都有这个属性,但是不同对象此属性不同
什么时候成员变量声明为实例变量?
—所有对象都这个属性并且所有对象的属性的值都是一样的
——所有的静态的数据都可采用类名的方式访问,也可以采用引用,但是建议采用类名的方式访问
——采用引用的方法访问的时候即使引用是null,也不会出现空指针异常,因为访问静态数据的时候不需要对象的存在
2022.3.18
-
Java中static关键字的作用和用法详细介绍
2020-09-03 23:48:30主要介绍了Java中static关键字的作用和用法详细介绍,本文讲解了static变量、静态方法、static代码块、static和final一块用等内容,需要的朋友可以参考下 -
Java下static关键字用法详解
2020-12-22 17:49:30Static关键字可以修饰什么? 从以下测试可以看出, static 可以修饰: 1. 语句块 2. 成员变量(但是不能修饰局部变量) 3. 方法 4. 接口(内部接口) 5. 类(只能修饰在类中的类, 即静态内部类) 6. ... -
Java静态static关键字原理详解
2020-08-25 05:19:43主要介绍了Java静态static关键字原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
java中static关键字用法详解
2020-08-29 20:15:08主要为大家详细介绍了java中static关键字的用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
[Java]关于Java中static关键字修饰类变量
2018-08-26 03:25:14Java中的static关键字修饰的类变量是静态变量,所有以此类实例化的对象共享此变量实体. 实例化的多个对象任何一个对Static修饰的变量操作后,其他的对象指向的此变量都变化. 下面是测试代码: /** * 测试Static...Java中的static关键字修饰的类变量是静态变量,所有以此类实例化的对象共享此变量实体.
实例化的多个对象任何一个对Static修饰的变量操作后,其他的对象指向的此变量都变化.
下面是测试代码:
/** * 测试Static修饰类中变量 * @author Freddy * */ public class test { static int a; int b; /*构造方法*/ public test(int x,int y) { this.a = x; this.b = y; } public static void main(String[] args) { System.out.println("现在实例化ST1"); test ST1 = new test(10,20); System.out.println("ST1.a旳值是"+ST1.a); System.out.println("ST1.b旳值是"+ST1.b); System.out.println("现在实例化ST2"); test ST2 = new test(30, 40); System.out.println("ST1.a旳值是"+ST1.a); System.out.println("ST1.b旳值是"+ST1.b); System.out.println("ST2.a旳值是"+ST2.a); System.out.println("ST2.b旳值是"+ST2.b); } }
以下是控制台输出的测试结果:
-
java中的static关键字
2021-03-09 00:29:26一、static代表着什么在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,当然也可以修饰代码块。...一、static代表着什么
在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,当然也可以修饰代码块。
Java把内存分为栈内存和堆内存,其中栈内存用来存放一些基本类型的变量、数组和对象的引用,堆内存主要存放一些对象。在JVM加载一个类的时候,若该类存在static修饰的成员变量和成员方法,则会为这些成员变量和成员方法在固定的位置开辟一个固定大小的内存区域(只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们),有了这些“固定”的特性,那么JVM就可以非常方便地访问他们。同时如果静态的成员变量和成员方法不出作用域的话,它们的句柄都会保持不变。同时static所蕴含“静态”的概念表示着它是不可恢复的,即在那个地方,你修改了,他是不会变回原样的,你清理了,他就不会回来了。
同时被static修饰的成员变量和成员方法是独立于该类的,它不依赖于某个特定的实例变量,也就是说它被该类的所有实例共享。所有实例的引用都指向同一个地方,任何一个实例对其的修改都会导致其他实例的变化。
二、怎么使用static
static可以用于修饰成员变量和成员方法,我们将其称之为静态变量和静态方法,直接通过类名来进行访问。
ClassName.propertyName
ClassName.methodName(……)
static修饰的代码块表示静态代码块,当JVM装载类的时候,就会执行这块代码,其用处非常大。
1、static变量
static修饰的变量我们称之为静态变量,没有用static修饰的变量称之为实例变量,他们两者的区别是:
静态变量是随着类加载时被完成初始化的,它在内存中仅有一个,且JVM也只会为它分配一次内存,同时类所有的实例都共享静态变量,可以直接通过类名来访问它。但是实例变量则不同,它是伴随着实例的,每创建一个实例就会产生一个实例变量,它与该实例同生共死。
把一个变量声明为静态变量通常基于以下三个目的:
作为共享变量使用
减少对象的创建
保留唯一副本
public class TestStatic {
public static int count = 0;
public static void main(String[] args){
TestStatic test1=new TestStatic();
System.out.println(test1.count);
TestStatic test2=new TestStatic();
test2.count++;
System.out.println(test1.count+" "+test2.count+" "+TestStatic.count);
}
}
=======================
0
1 1 1
可见,static变量并不是所在类的某个具体对象所有,而是该类的所有对象所共有的,静态变量既能被对象调用,也能直接拿类来调用。
2、static方法
static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。
因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。
总结一下,对于静态方法需要注意以下几点:
(1)它们仅能调用其他的static 方法。
(2)它们只能访问static数据。
(3)它们不能以任何方式引用this 或super。
3、static代码块
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。下面看个例子:
class Person{
private Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
boolean isBornBoomer() {
Date startDate = Date.valueOf("1946");
Date endDate = Date.valueOf("1964");
return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
}
}
isBornBoomer是用来判断这个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和birthDate两个对象,造成了空间浪费,如果改成这样效率会更好:
class Person{
private Date birthDate;
private static Date startDate,endDate;
static{
startDate = Date.valueOf("1946");
endDate = Date.valueOf("1964");
}
public Person(Date birthDate) {
this.birthDate = birthDate;
}
boolean isBornBoomer() {
return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
}
}
因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。
4. 静态内部类
内部类一般情况下使用不是特别多,如果需要在外部类里面定义一个内部类,通常是基于外部类和内部类有很强关联的前提下才去这么使用。
在说静态内部类的使用场景之前,我们先来看一下静态内部类和非静态内部类的区别:
非静态内部类对象持有外部类对象的引用(编译器会隐式地将外部类对象的引用作为内部类的构造器参数);而静态内部类对象不会持有外部类对象的引用
由于非静态内部类的实例创建需要有外部类对象的引用,所以非静态内部类对象的创建必须依托于外部类的实例;而静态内部类的实例创建只需依托外部类;
并且由于非静态内部类对象持有了外部类对象的引用,因此非静态内部类可以访问外部类的非静态成员;而静态内部类只能访问外部类的静态成员;
两者的根本性区别其实也决定了用static去修饰内部类的真正意图:
内部类需要脱离外部类对象来创建实例
避免内部类使用过程中出现内存溢出
第一种是目前静态内部类使用比较多的场景,比如JDK集合中的Entry、builder设计模式。
HashMap Entry:
builder设计模式:
public class Person {
private String name;
private int age;
private Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
}
public static class Builder {
private String name;
private int age;
public Builder() {
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age=age;
return this;
}
public Person build() {
return new Person(this);
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
// 在需要创建Person对象的时候
Person person = new Person.Builder().name("张三").age(17).build();
第二种情况一般出现在多线程场景下,非静态内部类可能会引发内存溢出的问题,比如下面的例子:
public class Task {
public void onCreate() {
// 匿名内部类, 会持有Task实例的引用
new Thread() {
public void run() {
//...耗时操作
};
}.start();
}
}
声明并创建了一个匿名内部类对象,该对象持有外部类Task实例的引用,如果在在run方法中做的是耗时操作,将会导致外部类Task的实例迟迟不能被回收,如果Task对象创建过多,会引发内存溢出。
优化方式:
public class Task {
public void onCreate() {
SubTask subTask = new SubTask();
subTask.start();
}
static class SubTask extends Thread {
@Override
public void run() {
//...耗时操作
}
}
}
三、static关键字的误区
1、static关键字会改变类中成员的访问权限吗?
与C/C++中的static不同,Java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字。看下面的例子就明白了:
提示错误"Person.age 不可视",这说明static关键字并不会改变变量和方法的访问权限。
2、能通过this访问静态成员变量吗?
虽然对于静态方法来说没有this,那么在非静态方法中能够通过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);
}
}
======================
33
这里面主要考查对this和static的理解。this代表什么?this代表当前对象,那么通过new Main()来调用printValue的话,当前对象就是通过new Main()生成的对象。而static变量是被对象所享有的,因此在printValue中的this.value的值毫无疑问是33。在printValue方法内部的value是局部变量,根本不可能与this关联,所以输出结果是33。在这里永远要记住一点:静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。
3、static能作用于局部变量么?
在C/C++中static是可以作用域局部变量的,但是在Java中切记:static是不允许用来修饰局部变量。不要问为什么,这是Java语法的规定。
4、static和final一块用表示什么?
static final用来修饰成员变量和成员方法,可简单理解为“全局常量”!
对于变量,表示一旦给值就不可修改,并且通过类名可以访问。
对于方法,表示不可覆盖,并且可以通过类名直接访问。
static执行顺序
对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
参考文献
-
java中static关键字的理解
2021-01-17 10:57:47static关键字我们经常接触,不过我们一直没有讨论过它到底是什么,有什么具体的作用,那static关键字是什么呢,有啥用呢? static是静态的意思,是一个修饰符,就像是一个形容词,是用来形容类、变量、方法的。 ... -
Java:static关键字
2022-03-10 19:04:121.static修饰成员方法:一般称作静态方法,只能通过类来访问,没有this,静态方法中不能访问类的非静态成员方法和非静态成员变量,非静态成员方法和非静态成员变量都必须依赖对象来调用。但是,非静态成员方法可以... -
Java中的static关键字全面解析
2020-09-02 04:11:28主要介绍了Java中的static关键字全面解析的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下 -
Java中static关键字的作用与用法
2021-02-07 15:02:12一、static关键字的特点: static是一个修饰符,用于修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。 1. static修饰成员方法 static修饰的方法一般称作静态方法,由于静态方法不依赖... -
Java中static关键字
2019-05-06 19:09:34Java中static关键字的作用static关键字用在属性上static关键字可以修饰在方法上12 static关键字用在属性上 语法: static 数据类型 变量名 1.带static关键字的是类属性 ,不带static关键字的是对象属性 2.类属性的... -
Java static关键字详解
2021-02-20 16:19:32static关键字 当在定义类的时候,类中都会有相应的属性和方法。而属性和方法都是通过创建本类对象调用的。当在调用对象的某个方法时,这个方法没有访问到对象的特有数据时,方法创建这个对象有些多余。可是不创建... -
JAVA面试题 static关键字详解
2020-10-16 17:06:13主要介绍了JAVA面试题 浅析Java中的static关键字,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
浅谈Java中static关键字的作用
2020-08-26 04:43:50主要介绍了Java中static关键字的作用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
java中Static关键字的含义及其作用
2020-07-29 14:14:38java中Static关键字的含义及其作用 点击链接查看 -
java--static关键字详解:
2022-04-08 12:23:43一.static关键字的用途 在《Java编程思想》P86页有这样一段话: “static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来... -
Java static关键字(超详细!)
2021-04-11 18:26:02所有static关键字修饰的都是类相关的,类级别的。 所有static修饰的,都是采用“类名.”的方式访问。 static修饰的变量:静态变量 static修饰的方法:静态方法 2.变量的分类: 变量根据声明的位置进行划分: 在... -
java中static关键字有什么用
2021-03-16 18:06:29java中static关键字有什么用发布时间:2020-12-14 09:56:40来源:亿速云阅读:99作者:小新这篇文章主要介绍了java中static关键字有什么用,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有... -
【Java基础】Java8新特性—接口中使用default和static关键字
2020-12-22 04:24:08Java 1.8对接口有两个方面的增强:接口中可以添加使用default或者static修饰的方法 增加default方法:又叫做接口扩展方法,即在不破坏java现有实现架构的情况下能往接口里增加新方法, default关键字可以给接口添加... -
static关键字有什么作用
2021-03-09 00:29:24今天主要学习下Java语言中的static关键字。static关键字的含义及使用场景static是Java50个关键字之一。static关键字可以用来修饰代码块表示静态代码块,修饰成员变量表示全局静态成员变量,修饰方法表示静态方法。... -
Java中的static关键字
2016-07-01 10:38:18在Java中,存在着两种类型的变量,一种是实例变量,另外一种是类变量,也称为静态变量,用static关键字来修饰。1.被static所修饰的变量和方法,可以直接通过类名来调用,而不必实例化对象,然后通过对象调用,虽然... -
java中static关键字的作用
2021-02-12 11:21:11java中static关键字主要有两种作用:第一:为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。第二,实现某个方法或属性与类而不是对象关联在一起简单来说,在Java语言中,static主要有5中使用... -
Java中static关键字用法总结[借鉴].pdf
2021-10-11 03:27:40Java中static关键字用法总结[借鉴].pdf -
浅谈java中static关键字修饰的几种用法
2021-03-04 08:02:41在java的关键字中,static和final是两个我们必须掌握的关键字。不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构。下面我们先来了解一下static关键字及其用法。...