精华内容
下载资源
问答
  • 静态变量:指在程序编译阶段就就分配好内存空间出现的意义:解决数据共享的问题。 1.静态局部变量:函数结束后,静态局部变量的内存空间不会被系统回收,下一次调用函数时使用上一次退出时的值。 2.静态局部变量存储...

    静态变量:指在程序编译阶段就就分配好内存空间
    出现的意义:解决数据共享的问题。
    1.静态局部变量:函数结束后,静态局部变量的内存空间不会被系统回收,下一次调用函数时使用上一次退出时的值。 
    2.静态局部变量存储在静态存储区
    3.静态局部变量如果未初始化,则编译器会将它初始化为0或者null

    静态全局变量:只能在它声明的文件中使用,不能使用extern关键字引用。
    静态全局变量和全局变量的区别:生命周期是相同的,但是静态全局变量的作用域缩小。
    静态全局变量只能在它声明的源文件中使用,不能被extern引用

    静态变量的生命周期均为整个源程序。

    类的静态成员和非静态成员变量的区别:
    每一个对象都会为它的非静态成员变量在内存中保留一块空间来存储各自的值,而对于类的静态成员变量整个类中只有一份拷贝,所有对象共享这块空间。

    全局变量的意义:方便数据共享;(增加静态变量的意义是限制作用域,用static修饰后不能被extern修饰,只能在本源文件使用)

    const用来限制一个变量是只读的,即不可变的:
    const修饰变量
    (1)常量指针:不能通过修改指针所指向的变量的值。但是指针可以指向别的变量。可以理解为指向常量的指针。
    const int *p或者int const *p
    (2)指针常量:指针本身是常量,指针本身不可以改变,但是指针指向的值是可以变的。
    int *const p
    (3)指向常量的常指针:const int * const p,指针不可以改变,指针指向的内容也不可以改变

    const修饰成员函数
    const int fun(const int a) const;
    (1)const int 修饰还回值,表示不能修改还回值
    (2)const int a修饰函数参数,表示函数参数a是不能改变的
    (3)fun() const修饰的是整个函数,如果这个函数不是类的成员函数,则const是无意义的,如果是类的成员函数,表示函数体内不能修改长远变量的值,增加程序的健壮性和鲁棒性。

    const修饰对象:
    const对象只能调用const的函数

    展开全文
  • 在日常开发过程中,静态变量和 静态方法 是我们常见的用法,Java中相信大家并不陌生了,那么在 Kotlin 中该如何使用呢? 其实很简单,只需要一个将变量和方法包含在 companion object 域中即可,比如这样: class...
  • Java类中可以定义一个static块,用于静态变量的初始化。如: public class Test { public static int _i; static { _i = 10 ; } } 当然最常用的初始化静态变量的操作是在声明变量时...
    public class Test {  
        static {  
            _i = 20;  
        }  
        public static int _i = 10;  
    
        public static void main(String[] args) {  
            System.out.println(_i);  
        }  
    }  

    上述代码会打印出什么结果来呢?10还是20?本文将以此代码为引子,着重讨论一下静态变量的初始化问题。

    问题1:静态变量如何初始化

    Java类中可以定义一个static块,用于静态变量的初始化。如:

    public class Test {  
        public static int _i;  
        static {  
            _i = 10;  
        }  
    }  

    当然最常用的初始化静态变量的操作是在声明变量时直接进行赋值操作。如:

    public class Test {  
        public static int _i = 10;  
    }  

    那么上述两例在本质上有什么区别吗?回答是没有区别。两例代码编译之后的字节码完全一致,通过 “javap -c”查看到的字节码如下:

    public class Test extends java.lang.Object{
    public static int _i;
    
    
    
    public Test();
      Code:
       0: aload_0
       1: invokespecial #1; //Method java/lang/Object."<init>":()V
       4: return
    
    static {};
      Code:
       0: bipush 10
       2: putstatic #2; //Field _i:I
       5: return
    }

    通过字节码还可以看出,当类的定义中不含有static块时,编译器会为该类提供一个默认的static块。当然这是在含有静态变量初始化操作的前提下。如果静态变量没有初始化操作,则编译器不会为之提供默认的static块。如:

    public class Test {  
        public static int _i;  
    }  

    其字节码的表现形式为:

    public class Test extends java.lang.Object{
    public static int _i;
    
    public Test();
      Code:
       0: aload_0
       1: invokespecial #1; //Method java/lang/Object."<init>":()V
       4: return
    
    }

    由于静态变量是通过赋值操作进行初始化的,因此可以通过静态函数返回值的方式为其初始化。如:

    public class Test {  
        public static int _i = init();  
    
        private static int init() {  
            return 10;  
        }  
    }  

    其本质与下面的代码相同:

    public class Test {  
        public static int _i;  
        static {  
            _i = init();  
        }  
    
        private static int init() {  
            return 10;  
        }  
    }  

    问题2:JDK如何处理static块

    类定义中可以存在多个static块吗?回答是可以。如:

    public class Test {  
        public static int _i;  
        static {  
            _i = 10;  
        }  
    
        public static void main(String[] args) {  
        }  
    
        static {  
            _i = 20;  
        }  
    }  

    此类编译之后的字节码为:

    public class Test extends java.lang.Object{
    public static int _i;
    
    
    
    public Test();
      Code:
       0: aload_0
       1: invokespecial #1; //Method java/lang/Object."<init>":()V
       4: return
    
    public static void main(java.lang.String[]);
      Code:
       0: return
    
    static {};
      Code:
       0: bipush 10
       2: putstatic #2; //Field _i:I
       5: bipush 20
       7: putstatic #2; //Field _i:I
       10: return
    
    }

    观察static{}部分可以看出,上例的代码与下面的代码效果一致:

    public class Test {  
        public static int _i;  
    
        public static void main(String[] args) {  
        }  
    
        static {  
            _i = 10;  
            _i = 20;  
        }  
    }  

    此例可以证明,不仅类定义中可以有多个static块,而且在编译时编译器会将多个static块按照代码的前后位置重新组合成一个static块。

    问题3:如何看待静态变量的声明

    静态变量存放在常量池之中。如何证明呢?如:

    public class Test {  
        public static int _i = 10;  
    }  

    使用“javap -c -verbose”查看其字节码的内容如下:

    public class Test extends java.lang.Object
      SourceFile: "Test.java"
      minor version: 0
      major version: 49
      Constant pool:
    const #1 = Method #4.#14; //  java/lang/Object."<init>":()V
    const #2 = Field #3.#15; //  Test._i:I
    const #3 = class #16; //  Test
    const #4 = class #17; //  java/lang/Object
    const #5 = Asciz _i;
    const #6 = Asciz I;
    const #7 = Asciz <init>;
    const #8 = Asciz ()V;
    const #9 = Asciz Code;
    const #10 = Asciz LineNumberTable;
    const #11 = Asciz <clinit>;
    const #12 = Asciz SourceFile;
    const #13 = Asciz Test.java;
    const #14 = NameAndType #7:#8;//  "<init>":()V
    const #15 = NameAndType #5:#6;//  _i:I
    const #16 = Asciz Test;
    const #17 = Asciz java/lang/Object;
    
    
    {
    public static int _i;
    
    
    public Test();
      Code:
       Stack=1, Locals=1, Args_size=1
       0: aload_0
       1: invokespecial #1; //Method java/lang/Object."<init>":()V
       4: return
      LineNumberTable: 
       line 2: 0
    
    
    
    static {};
      Code:
       Stack=1, Locals=0, Args_size=0
       0: bipush 10
       2: putstatic #2; //Field _i:I
       5: return
      LineNumberTable: 
       line 3: 0
    
    }

    我们看到,常量池中const #2指向的就是Test._i,也就是静态变量。静态变量被保存到常量池中的工作原理这里不深入讨论。在此需要注意的是:

    静态变量的声明与初始化是两个不同的操作;
    静态变量的声明在编译时已经明确了内存的位置。
    如:

    public class Test {  
        public static int _i = 10;  
    }  

    上述代码的本质可以视为:

    public class Test {  
        // 静态变量的声明  
        public static int _i;  
    
        // 静态变量的初始化  
        static {  
            _i = 10;  
        }  
    }  

    由于静态变量的声明在编译时已经明确,所以静态变量的声明与初始化在编码顺序上可以颠倒。也就是说可以先编写初始化的代码,再编写声明代码。如:

    public class Test {  
        // 静态变量的初始化  
        static {  
            _i = 10;  
        }  
    
        // 静态变量的声明  
        public static int _i;  
    }  

    对初始问题的解答
    解答了上述三个问题,让我们再来看看开篇提到的问题。代码如下:

    public class Test {  
        static {  
            _i = 20;  
        }  
        public static int _i = 10;  
    
        public static void main(String[] args) {  
            System.out.println(_i);  
        }  
    }  

    其本质可以用下面的代码表示:

    public class Test {  
        static {  
            _i = 20;  
        }  
        public static int _i;  
        static {  
            _i = 10;  
        }  
    
        public static void main(String[] args) {  
            System.out.println(_i);  
        }  
    }  

    再简化一下,可以表示为:

    public class Test {  
        public static int _i;  
    
        static {  
            _i = 20;  
            _i = 10;  
        }  
    
        public static void main(String[] args) {  
            System.out.println(_i);  
        }  
    }  

    至此,代码已经明确告诉我们打印结果是什么了!
    这里写图片描述

    参考:
    https://blog.csdn.net/darxin/article/details/5293427(Java静态变量的初始化)

    展开全文
  • 静态(伴生对象)关键字:companion object 1.将变量和方法写在这个伴生对象中,外部就直接可以类名+点 调用。 2.但实际上在运行时,这些成员仍然是真实对象的实例的成员。 属性修饰符解释: 1. const val ...

    一. 伪静态(伴生对象)关键字:companion object

            1.将变量和方法写在这个伴生对象中,外部就直接可以类名+点 调用。

            2.但实际上在运行时,这些成员仍然是真实对象的实例的成员。

     属性修饰符解释:

           1. const val :公共常量 ,且 const只能修饰 val

           2. val :私有常量

    class Constant {
        companion object {
    
            const val NAME= "CSDN-深海呐"
            
            fun getName(){
                
            }
    
        }
    
    }

    二. 真实静态 注解:@JvmField  与 @JvmStatic

     相对优势:  

            1.底层实现与JAVA静态无异

            2.Java与Kotlin混合开发时,Java代码中可直接类名+点 调用

    
    class Constant {
        companion object {
    
            @JvmField
            val NAME= "CSDN-深海呐"  //不可以用const val
    
            @JvmStatic        
            fun getName(){
                
            }
    
        }
    
    }
    
            
    展开全文
  • Hello JNI本文主要介绍以下几个函数的使用:GetObjectClassGetFieldID,GetStaticFieldIDGet< Type>Field,GetStatic< Type>FieldSet< Type>Field,SetStatic< Type>Field案例介绍:通过JNI获取并修改Java变量值...

    对于JNI的基本使用请移步:Hello JNI

    本文主要介绍以下几个函数的使用:

    GetObjectClass

    GetFieldID,GetStaticFieldID

    Get< Type>Field,GetStatic< Type>Field

    Set< Type>Field,SetStatic< Type>Field

    案例介绍:通过JNI获取并修改Java中类的变量值

    本文也是基于上面的代码继续添加:

    JniDemo中添加name,age变量,和accessField(),accessStaticField()方法。

    public class JniDemo {
        //路径:/JNIDemo/app/build/intermediates/classes/debug/com/test/git/jnidemo/JniUtil/JniDemo.class
    
        public String name = "Lucy";
    
        public static int age = 10;
    
        public native String helloJni();
    
        //修改字段值
        public native void accessField();
        //修改字段值(静态方法)
        public native void accessStaticField();
        static {
            System.loadLibrary("NdkJniDemo");
        }
    }

    生成相应的头文件:

    JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_accessField
      (JNIEnv *, jobject);
    
    JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_accessStaticField
      (JNIEnv *, jobject);

    JniDemo.cpp

    通过JNI获取并修改Java中变量值

    对于变量的签名可以参考:JNI类型

    JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_accessField
            (JNIEnv *env, jobject obj){
        //1.获取jclass obj是JniDemo对象, JNIDemo.class
        jclass cls = (*env).GetObjectClass(obj);
    
        //2.获取jfieldID
        //name:属性名称,sig:属性签名
        //jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)
        jfieldID fid = (*env).GetFieldID(cls, "name", "Ljava/lang/String;");
    
        //3.修改name的值
    
        //a.获取name属性的值 Get<Type>Field
        jstring jstr = (jstring) (*env).GetObjectField(obj, fid);
    
        //b.jstring转成c字符串
        //isCopy:true复制, false不复制,或者NULL
        //const char* GetStringUTFChars(jstring string, jboolean* isCopy)
        const char* c_str = (*env).GetStringUTFChars(jstr, JNI_FALSE);
    
        //c.拼接得到新的字符串
        char new_char[40] = "changed ";
        //复制c_str 到 new_char
        strcat(new_char, c_str);
    
        //d.c字符串转换成String
        jstring new_jstr = (*env).NewStringUTF(new_char);
    
        //e.修改name值
        //Set<Type>Field
        (*env).SetObjectField(obj, fid, new_jstr);
    
        //释放资源
        (*env).ReleaseStringUTFChars(jstr, c_str);
    };
    通过JNI获取并修改Java中静态变量值
    JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_accessStaticField
            (JNIEnv *env, jobject obj){
        //1.获取jclass
        jclass cls = env->GetObjectClass(obj);
        //2.获取age的jfieldID 注意用GetStaticFieldID方法
        jfieldID jfid = env->GetStaticFieldID(cls, "age", "I");
        //3.通过jfid获取age的属性值,注意用GetStaticIntField
        jint jage = env->GetStaticIntField(cls, jfid);
        jage ++;
        //4.修改age的属性值,注意用GetStaticIntField
        env->SetStaticIntField(cls,jfid, jage);
    };

    MainActivity调用

    public class MainActivity extends AppCompatActivity {
        private static final String TAG = "MainActivity-";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            JniDemo jd = new JniDemo();
            Log.i(TAG, "helloJni->" + jd.helloJni());
    
            Log.i(TAG, "name修改前: " + jd.name);
            jd.accessField();
            Log.i(TAG, "name修改后: " + jd.name);
    
            Log.i(TAG, "age修改前: " + jd.age);
            jd.accessStaticField();
            Log.i(TAG, "age修改后: " + jd.age);
    
        }
    }

    执行结果:

    09-24 12:32:44.021 19457-19457/com.test.git.jnidemo I/MainActivity-: helloJni->hello jni
    09-24 12:32:44.021 19457-19457/com.test.git.jnidemo I/MainActivity-: name修改前: Lucy
    09-24 12:32:44.021 19457-19457/com.test.git.jnidemo I/MainActivity-: name修改后: changed Lucy
    09-24 12:32:44.021 19457-19457/com.test.git.jnidemo I/MainActivity-: age修改前: 11
    09-24 12:32:44.021 19457-19457/com.test.git.jnidemo I/MainActivity-: age修改后: 12

    扩展

    JNI获取并修改Java中Array的值

    JniDemo.class

    public String[] courses = {"语文", "数学"};
    public native void accessArrayField();

    com_test_git_jnidemo_JniUtil_JniDemo.h头文件

    JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_accessArrayField
      (JNIEnv *, jobject);

    JniDemo.cpp

    JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_accessArrayField
            (JNIEnv *env, jobject jobj){
        jclass cls = env->GetObjectClass(jobj);
        jfieldID fid = env->GetFieldID(cls, "courses", "[Ljava/lang/String;");
        jobjectArray jarray = (jobjectArray) env->GetObjectField(jobj, fid);
        env->SetObjectArrayElement(jarray, 0, env->NewStringUTF("英语"));
    };

    MainActivity.java

            Log.i(TAG, "courses修改前: " + jd.courses[0]);
            jd.accessArrayField();
            Log.i(TAG, "courses修改后: " + jd.courses[0]);

    打印结果:

    09-24 14:36:23.041 18001-18001/com.test.git.jnidemo I/MainActivity-: courses修改前: 语文
    09-24 14:36:23.042 18001-18001/com.test.git.jnidemo I/MainActivity-: courses修改后: 英语
    展开全文
  • Java静态成员

    千次阅读 2018-12-29 16:12:34
    静态变量也叫变量,非静态变量也叫实例变量;静态方法也叫方法,非静态方法也叫实例方法。静态成员最主要的特点是它不属于任何一个的对象,它不保存在任意一个对象的内存空间中,而是保存在的公共区域中,...
  • 上篇文章JNI访问Java对象的成员介绍了如何在JNI层回调Java对象的成员(变量和方法),这篇文章是上篇文章 的姊妹篇,介绍在JNI层如何回调Java类静态成员(变量和方法)。 例子 首先呢,还是需要做一些准备工作,先...
  • 对于java中的static我们并不陌生,并且使用的很平凡,那么在kotlin中,我们该如何定义静态变量和静态方法呢? 首先,我们要明确一点,kotlin中是没有static字段的,也就是说我们并不能像java中那样,直接定义静态,...
  • PHP中 static const 变量的区别

    千次阅读 2017-12-11 13:45:05
    php中static与const变量的区别
  • java 声明静态Map常量的一种简单方式

    万次阅读 2019-05-24 15:17:51
    常用的声明方式(使用静态代码块): public final static Map map = new HashMap(); static { map.put("key1", "value1"); map.put("key2", "value2"); } @SuppressWarnings("serial") private static...
  • 静态变量和常量的区别

    万次阅读 2017-03-25 22:55:58
    共同点: 1、static和const在编译时直接分配内存。 区别: ...1、(本质)static是类型引用,const是实例引用。...2、(初始化)静态变量的初始值必须是一个常量。...4、(内存)静态变量存放在全局数据区中,伴随着这
  • 讲白了,这个东西你就理解成是替代java语言中的静态变量 static field 或者 static function的作用就可以了。 不要把他想的过于复杂。 Kotlin调用Kotlin的场景 直接上代码 显然 如果只是Kotlin调用Kotlin的情况 ...
  • (1)数据类型(int、char....)对于const而言是透明的。(const修饰它的直接右边,不能做左值) 如: (const int SIZE =10;)等同于(int const SIZE =10;) (const int * p=&a;)等同于(int const *p=&...
  • java 静态变量和静态块底层原理

    千次阅读 2013-11-04 15:57:29
    Java静态变量的初始化(static块的本质) 在网上看到了下面的一段代码: public class Test { static { _i = 20; } public static int _i = 10; public static void main(String[] args) {
  • 数据成员可以分为静态变量和非静态变量两种。  静态成员(Java中也称为成员):静态中的成员加入static修饰符,即是静态成员。可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员...
  • JNI开发-C/C++获取Java静态全局变量

    千次阅读 2018-07-10 18:53:54
    在JNI开发时,C/C++函数有时需要获取Java静态全局变量,此篇主要是获取CCallJavaTools静态全局变量strContent2;   1. Java的com.niubashaoye.ndk.jni.CCallJavaTools: public class CCallJavaTools { ...
  • 静态变量和静态方法的定义 //Define.kt文件 class Define{ companion object { val GUIDE_TYPE: String = "GUIDE_TYPE"//定义静态变量 fun open(){//定义静态方法 } } } 静态变量和静态方法的使用 ...
  • 在日常开发过程中,静态变量和 静态方法 是我们常见的用法,Java中相信大家并不陌生了,那么在 Kotlin 中该如何使用呢?其实很简单,只需要一个将变量和方法包含在 companion object 域中即可,比如这样: ...
  • 静态变量初始化线程安全

    千次阅读 2019-01-03 17:47:36
    前言 c++11 担保了 static 变量的初始化...c++ 98/03 关于静态初始化标准 简言而之,它只是担保了local static 变量的初始化发生于当该表达式第一次执行时。 The zero-initialization (8.5) of all local objects...
  • 静态变量与全局变量

    千次阅读 2016-08-03 11:18:02
    1.生存周期不同 全局变量:全局区(静态区)(static):全局变量和静态变量是存储在一起的,初始化过的全局变量和静态变量在同一块区域,未初始化的全局变量和静态变量存放在一块相邻的区域内。此区域由系统在程序...
  • 静态变量初始化

    2017-11-03 11:59:00
    Java类中可以定义一个static块,用于静态变量的初始化。如: public class Test { public static int _i; static { _i = 10; } } 当然最常用的初始化静态变量的操作是在声明变量时直接进行赋值操作。如: ...
  • JAVA中的关键字static,final和const

    万次阅读 多人点赞 2017-03-09 08:41:57
    一、static1.static修饰变量C的局部变量,全局变量(即外部变量)和静态变量局部变量:在函数内定义的变量,采用动态存储方式。全局变量:在函数外定义的变量,采用静态存储方式。extern: 外部变量的作用域从定义点...
  • Kotlin开发Android项目之静态方法、静态变量使用示例 1.Kotlin定义一个都是静态方法的   Kotlin定义一个都是静态方法的,比如项目中比较常见的工具,只需要将class换为object即可,下面是Java写法和...
  • Kotlin中使用静态变量和静态方法

    千次阅读 2019-07-15 19:22:24
    在日常开发过程中,静态变量和 静态方法 是我们常见的用法,Java中相信大家并不陌生了,那么在 Kotlin 中该如何使用呢?其实很简单,只需要一个将变量和方法包含在 companion object 域中即可,比如这样: ...
  • 因为在Excel中VBA是默认隐藏且禁止运行宏的,所以首先介绍如何在Excel中启用VBA,然后介绍基础的变量、常量循环、判断语句
  • 肆——Java最常用的编程元素:常量与变量 一、常量 一般来说,所有的程序设计语言都需要定义常量(Constant)。所谓常量,就是固定不变的量,其一旦被定义并赋初值后,它的值就不能再被改变。 1.声明常量 在Java...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 41,183
精华内容 16,473
关键字:

java类的静态变量与const

java 订阅