我们高中class里有一个static女神

static关键字在Java编程中经常用到,今天我们来讲解一下。

在《Java编程思想》P86页有这样一段话:
“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”

这段话虽然只是说明了static方法的特殊之处,但是可以看出static关键字的基本作用,简而言之,一句话来描述就是:
方便在没有创建对象的情况下来进行调用(方法/变量)

显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。

static可以用来修饰类的成员方法、类的成员变量,另外也可以编写static代码块来优化程序性能。

在类中,用static声明的成员变量为静态成员变量,也成为类变量。类变量的生命周期和类相同,在整个应用程序执行期间都有效。

注:
static修饰的成员变量和方法,从属于类
普通变量和方法从属于对象
静态方法不能调用非静态成员,编译会报错

1、static方法

static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。

但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。

我们看个例子:
在这里插入图片描述
从上面代码里看出:

静态方法print2()中调用非静态成员变量s2,编译失败。这是因为,在编译期并没有对象生成,s2变量根本就不存在。

静态方法print2()中调用非静态方法print1(),编译失败。这是因为,编译器无法预知在非静态成员方法print1()中是否访问了非静态成员变量,所以也禁止在静态方法中调用非静态成员方法。

非静态成员方法print1()访问静态成员方法print2()和变量s1是没有限制的

所以,如果想在不创建对象的情况下调用某个方法,就可以将这个方法设置为static。最常见的静态方法就是main方法,这就是为什么main方法是静态方法就一目了然了,因为程序在执行main方法的时候没有创建任何对象,只有通过类名来访问。

注:static方法是属于类的,不属于实例对象。在JVM加载类时,就已经存在内存中,不会被虚拟机GC回收掉,这样内存负荷会很大。而非static方法会在运行完毕后被虚拟机GC掉,减轻内存压力。

2、static变量

static变量也称为静态变量,静态变量和非静态变量的区别:
静态变量被所有对象共享,在内存中只有一个副本,在类初次加载的时候才会初始化。
非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
注:static成员变量初始化顺序按照定义的顺序来进行初始化

3、static块

static关键字还有一个比较关键的作用就是用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。

4、static关键字的误区

(1)static关键字会改变类中成员的访问权限吗?
在这里插入图片描述
提示错误"Animal.age 不可见",这说明static关键字并不会改变变量和方法的访问权限。
(2)能通过this访问静态成员变量吗?

public class Test {
	
	static int value = 100;
	 
    public static void main(String[] args) throws Exception{
        new Test().printValue();
    }
 
    private void printValue(){
        int value = 1;
        System.out.println(this.value);
    }
}

输出结果为:100
this代表什么?this代表当前对象,那么通过new Test()来调用printValue的话,当前对象就是通过new Test()生成的对象。而static变量是被对象所享有的,因此在printValue中的this.value的值毫无疑问是100。在printValue方法内部的value是局部变量,根本不可能与this关联,所以输出结果是100。
注:静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)
(3)static能作用于局部变量么?
static是不允许用来修饰局部变量。Don’t ask why,这是Java语法的规定。
在这里插入图片描述
方法里用static修饰局部变量,编译直接报错!

欢迎小伙伴们关注转发点赞,谢谢~~
浏览更多文章可关注微信公众号:diggkr

在 Unreal Engine C++ 中,类名后使用 `StaticClass()` 是一种常见的模式,用于获取该类的 `UClass` 对象指针。`UClass` 是 Unreal Engine 的反射系统核心之一,它提供了运行时对类的元信息访问能力,包括类名、父类、属性、函数等信息[^2]。 例如,对于类 `AMyActor`,调用 `AMyActor::StaticClass()` 会返回一个指向该类的 `UClass` 对象的指针。这个方法通常是一个静态成员函数,其定义如下: ```cpp static UClass* StaticClass() { static UClass* Class = nullptr; if (!Class) { // 构建类信息 Class = GetPrivateStaticClassBody(StaticPackage(), TEXT("AMyActor"), AActor::StaticClass()); } return Class; } ``` 该函数确保了类信息的延迟初始化,并且只在首次调用时构建,从而避免不必要的性能开销。`StaticClass()` 在引擎的多个模块中被广泛使用,例如在垃圾回收、序列化、蓝图系统以及反射调用中,都依赖于此类信息来实现动态行为[^1]。 此外,`StaticClass()` 通常与 `GENERATED_BODY()` 宏一起使用,这是 Unreal Engine 的代码生成系统的一部分。当使用 `UCLASS()` 宏定义一个类时,引擎会在编译时自动生成反射数据,并通过 `StaticClass()` 提供访问接口。 ### 示例代码 以下是一个典型的类定义,展示了 `StaticClass()` 的使用方式: ```cpp UCLASS() class MYPROJECT_API AMyActor : public AActor { GENERATED_BODY() public: // 构造函数 AMyActor(); // 获取类的 UClass 对象 static UClass* StaticClass() { static UClass* Class = nullptr; if (!Class) { Class = GetPrivateStaticClassBody(StaticPackage(), TEXT("AMyActor"), AActor::StaticClass()); } return Class; } }; ``` ### 相关问题 1. 如何在 Unreal Engine C++ 中自定义反射信息? 2. `UCLASS()` 宏在 Unreal Engine 中的作用是什么? 3. `GENERATED_BODY()` 宏是如何影响类的反射功能的? 4. 为什么 `StaticClass()` 方法通常实现为延迟初始化? 5. `GetPrivateStaticClassBody` 函数在 Unreal Engine 中的具体作用是什么?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值