static用法小结

static用法小结
static用法小结

static关键字是C, C++中都存在的关键字, 它主要有三种使用方式, 其中前两种只指在C语言中使用, 第三种在C++中使用(C,C++中具体细微操作不尽相同, 本文以C++为准).

(1)局部静态变量

(2)外部静态变量/函数

(3)静态数据成员/成员函数

下面就这三种使用方式及注意事项分别说明

一、局部静态变量

在C/C++中, 局部变量按照存储形式可分为三种auto, static, register

(谭浩强, 第174-175页)

与auto类型(普通)局部变量相比, static局部变量有三点不同

1. 存储空间分配不同

auto类型分配在栈上, 属于动态存储类别, 占动态存储区空间, 函数调用结束后自动释放, 而static分配在静态存储区, 在程序整个运行期间都不释放. 两者之间的作用域相同, 但生存期不同.

2. static局部变量在所处模块在初次运行时进行初始化工作, 且只操作一次

3. 对于局部静态变量, 如果不赋初值, 编译期会自动赋初值0或空字符, 而auto类型的初值是不确定的. (对于C++中的class对象例外, class的对象实例如果不初始化, 则会自动调用默认构造函数, 不管是否是static类型)

特点: static局部变量的”记忆性”与生存期的”全局性”

所谓”记忆性”是指在两次函数调用时, 在第二次调用进入时, 能保持第一次调用退出时的值.

示例程序一

#include

using namespace std;

void staticLocalVar()

{

static int a = 0; // 运行期时初始化一次, 下次再调用时, 不进行初始化工作

cout<<"a="<

++a;

}

int main()

{

staticLocalVar(); // 第一次调用, 输出a=0

staticLocalVar(); // 第二次调用, 记忆了第一次退出时的值, 输出a=1

return 0;

}

应用:

利用”记忆性”, 记录函数调用的次数(示例程序一)

利用生存期的”全局性”, 改善”return a pointer / reference to a local object”的问题. Local object的问题在于退出函数, 生存期即结束,. 利用static的作用, 延长变量的生存期.

// IP address to string format

// Used in Ethernet Frame and IP Header analysis

const char * IpToStr(UINT32 IpAddr)

{

static char strBuff[16]; // static局部变量, 用于返回地址有效

const unsigned char *pChIP = (const unsigned char *)&IpAddr;

sprintf(strBuff, "%u.%u.%u.%u", pChIP[0], pChIP[1], pChIP[2], pChIP[3]);

return strBuff;

}

注意事项:

1. “记忆性”, 程序运行很重要的一点就是可重复性, 而static变量的”记忆性”破坏了这种可重复性, 造成不同时刻至运行的结果可能不同.

2. “生存期”全局性和唯一性. 普通的local变量的存储空间分配在stack上, 因此每次调用函数时, 分配的空间都可能不一样, 而static具有全局唯一性的特点, 每次调用时, 都指向同一块内存, 这就造成一个很重要的问题---- 不可重入性!!!

这样在多线程程序设计或递归程序设计中, 要特别注意这个问题.

(不可重入性的例子可以参见(影印版)第103-105页)

下面针对示例程序二, 分析在多线程情况下的不安全性.(为方便描述, 标上行号)

①const char * IpToStr(UINT32 IpAddr)

②{

③static char strBuff[16]; // static局部变量, 用于返回地址有效

④const unsigned char *pChIP = (const unsigned char *)&IpAddr;

⑤sprintf(strBuff, "%u.%u.%u.%u", pChIP[0], pChIP[1], pChIP[2], pChIP[3]);

⑥return strBuff;

⑦}

假设现在有两个线程A,B运行期间都需要调用IpToStr()函数, 将32位的IP地址转换成点分10进制的字符串形式. 现A先获得执行机会, 执行IpToStr(), 传入的参数是0x0B090A0A, 顺序执行完应该返回的指针存储区内容是:”10.10.9.11”, 现执行到⑥时, 失去执行权, 调度到B线程执行, B线程传入的参数是

0xA8A8A8C0, 执行至⑦, 静态存储区的内容是192.168.168.168. 当再调度到A执行时, 从⑥继续执行, 由于strBuff的全局唯一性, 内容已经被B线程冲掉, 此时返回的将是192.168.168.168字符串, 不再是10.10.9.11字符串.

二、外部静态变量/函数

在C中static有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。, 但为了限制全局变量/函数的作用域, 函数或变量前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。注意此时, 对于外部(全局)变量, 不论是否有static限制, 它的存储区域都是在静态存储区, 生存期都是全局的. 此时的static只是起作用域限制作用, 限定作用域在本模块(文件)内部.

使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。

示例程序三:

//file1.cpp

static int varA;

int varB;

extern void funA()

{

……

}

static void funB()

{

……

}

//file2.cpp

extern int varB; // 使用file1.cpp中定义的全局变量

extern int varA; // 错误! varA是static类型, 无法在其他文件中使用

extern vod funA(); // 使用file1.cpp中定义的函数

extern void funB(); // 错误! 无法使用file1.cpp文件中static函数

三、静态数据成员/成员函数(C++特有)

C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数. 这是与普通成员函数的最大区别, 也是其应用所在, 比如在对某一个类的对象进行计数时, 计数生成多少个类的实例, 就可以用到静态数据成员. 在这里面, static既不是限定作用域的, 也不是扩展生存期的作用, 而是指示变量/函数在此类中的唯一性. 这也是”属于一个类而不是属于此类的任何特定对象的变量和函数”的含义. 因为它是对整个类来说是唯一的, 因此不可能属于某一个实例对象的. (针对静态数据成员而言, 成员函数不管是否是static, 在内存中只有一个副本, 普通成员函数调用时, 需要传入this指针, static成员函数调用时, 没有this指针. )

请看示例程序四((影印版)第59页)

class EnemyTarget {

public:

EnemyTarget() { ++numTargets; }

EnemyTarget(const EnemyTarget&) { ++numTargets; }

~EnemyTarget() { --numTargets; }

static size_t numberOfTargets() { return numTargets; }

bool destroy(); // returns success of attempt to destroy EnemyTarget object

private:

static size_t numTargets; // object counter

};

// class statics must be defined outside the class;

// initialization is to 0 by default

size_t EnemyTarget::numTargets;

在这个例子中, 静态数据成员numTargets就是用来计数产生的对象个数的.

另外, 在设计类的多线程操作时, 由于POSIX库下的线程函数pthread_create()要求是全局的, 普通成员函数无法直接做为线程函数, 可以考虑用Static成员函数做线程函数.

java static 的使用方法

类方法 方法被声明为static后,则称为类方法。类方法相对于实例方法,前者区别于后者的地方:前者为属于该类的所有实例对象共享,无须实例化对象,仅通过类名即可访问(当然,是否能够直接访问,还取决于所声明的访问权限)。 因为被static化后产生上述特殊性,所以static变量都会在类被加载时初始化,而类方法也同时随类加载而进驻内存。先来段代码热热身吧~ 上段代码,输出结果为: null A Class 由结果可知,即字符串prvateStr的值为空。嘿,可别认为值应该是下面那样啊。那样 的话,进行下去就太具挑战性了。 A Class A Class 请记住一点,类变量初始化的顺序与其在类中的赋值顺序一致。

重写(覆盖) 或许大家对于面向对象编程语言最初的印象就是其语言单元是以父类、子类的关系存在着,而构建这一关系的就是继承机制了。子类可以继承父类一切非private的变量与方法,并且可以添加自己的变量与方法。在构建一个系统时,这机制让我们强烈地感觉到编程是一 门优雅的艺术。 来段小小的代码简单地展示下: 结果如下: Jack I am a thinking animal, and a Programmer

如上,子类Programmer中并没定义字符串characteristic,但我们却在其方法printProfession()中调用了;同样,我们正常使用了父类定义的printName()方法。而这就 是继承的简单实现。 继承不仅仅带来以上特性。它还赋予子类重写(覆盖)父类方法的能力(因为旨在讲类方法的重写,所以这儿就不讲重载以及变量在继承机制中的问题了)。方法的重写(覆盖):继承父类的子类,可以通过拟具有相同方法名与参数组的方法来重写父类中对应的方法,从而让子类更个性化。又因为重写(覆盖)的出现,多态也随之产生。多态:通过父类变量可以引用其子类对象,从而调用子类中那些继承自自己并被重写(覆盖)的方法。

Java--static关键字的

static关键字 如果使用一个类则会在实例化对象时分别开辟栈内存及堆内存,在堆内存中要保存对象中的属性,每个对象都有自己的属性,如果你现在有些属性希望被共享,则就必行将其声明为static属性,而且一个属性声明为static属性,可以直接使用类名称进行调用,如果一个类中的方法想由类调用,则可以声明为static方法。 一.使用static声明属性 如果程序中使用static声明属性,则属性成为全局属性(有些也称为静态属性),那么声明为全局属性到底有什么用吶?观察以下代码: class Person{ // 定义Person类 String name ; // 定义name属性,暂时不封装 int age ; // 定义age属性,暂时不封装 String country = "A城" ; // 定义城市属性,有默认值 public Person(String name,int age){ https://www.360docs.net/doc/c64812196.html, = name ; this.age = age; } public void info(){ // 得到信息 System.out.println("姓名:" + https://www.360docs.net/doc/c64812196.html, + ",年龄:" + this.age + ",城市:" + country) ; } }; public class StaticDemo01{ public static void main(String args[]){ Person p1 = new Person("张三",30) ; // 实例化对象 Person p2 = new Person("李四",31) ; // 实例化对象 Person p3 = new Person("王五",32) ; // 实例化对象 https://www.360docs.net/doc/c64812196.html,() ; https://www.360docs.net/doc/c64812196.html,() ; https://www.360docs.net/doc/c64812196.html,() ; } }; 运行结果: 姓名:张三,年龄:30,城市:A城 姓名:李四,年龄:31,城市:A城 姓名:王五,年龄:32,城市:A城 以上代码,为了观察方便没有使用private关键字进行封装。以上的程序是一个简单的程序,但是代码中有些不妥之处。 实际上,如果现在假设此城市不叫A城,而改为了B城,而且此类产生了200个对象,那么就意味着要把这些对象的城市属性全部修改一边。这样显然是不行的。最好的方法是修改一次就可以,此时可以把城市属性使用static关键字进行声明,将其变为公共属性。 使用static声明属性: class Person{ // 定义Person类

JAVA语言中的final修饰符

final关键字可用于修饰类,变量和方法,final关键字有点类似c#里的sealed关键字(如果大家学过C#就知道),它用于表示它修饰的类,方法和变量不可改变。 final变量 final修饰变量时,表示该变量一旦获得了初始值就不可改变,final既可修饰成员变量(包括类变量和实例变量),也可以修饰局部变量,形参。严格来说final修饰的变量不要被改变,一旦获得初始值之后,该final变量的值就不能被重新赋值。 因为final变量获得初始值之后不能被重新赋,因此final修饰成员变量和修饰局部变量时有一定的不同:下面我将会写到有哪些方面的不同,还有就是为什么会不同。 final修饰成员变量 成员变量是随类初始化或对象初始化而初始化的。当类初始化时,系统会为该类属性分配内存,并分配默认值;当创建对象时,系统会为该对象的实例属性分配内存,并分配默认值。也就是说,当执行静态初始化块时可以对类属性赋初始值,当执行普通初始块,构造器时可对实例属性赋初始值。因此,成员变量的初始值可以在定义该变量时指定默认值,可以在初始化块,构造器中指定初始值,否则,成员变量的初始值将是由系统自动分配的初始值。 对于final修饰的成员变量而言,一旦有了初始值之后,就不能重新赋值,因此不可以在普通方法中对成员变量重新赋值。成员变量只能在定义该成员变量时指定默认值,或者在静态初始化块,初始化块,构造器中为成员变量指定初始值,如果既没有在定义成员变量时指定初始值,也没有在初始化块,构造器中为成员变量指定初始值,那么这些成员变量的值将一直是0,\u0000,false null这些成员变量也就失去了存在的意义。 因此当使用final修饰成员变量的时候,要么在定义成员变量时候指定初始值,要么

c语言关键字的用法详解优选稿

c语言关键字的用法详 解 集团文件版本号:(M928-T898-M248-WU2669-I2896-DQ586-M1988)

1.Static用法 1.1static声明的变量在C语言中有两方面的特征: 1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。 2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。 1.2特点 A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度; B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度; C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题; D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数) E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。 函数前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函

数)。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。 扩展分析:术语static有着不寻常的历史.起初,在C中引入关键字st atic是为了表示退出一个块后仍然存在的局部变量。随后,static在C 中有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。为了避免引入新的关键字,所以仍使用static关键字来表示这第二种含义。最后,C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数(与Java 中此关键字的含义相同)。 1.3关键字static的作用是什么? 1.4 这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用: 1.4.1在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 int testStatic() { int x=1; x++; return x; }

Java关键字final使用总结

Java关键字final使用总结 一、final 根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。 final类不能被继承,没有子类,final类中的方法默认是final的。 final方法不能被子类的方法覆盖,但可以被继承。 final成员变量表示常量,只能被赋值一次,赋值后值不再改变。 final不能用于修饰构造方法。 注意:父类的private成员方法是不能被子类方法覆盖的,因此private 类型的方法默认是final类型的。 1、final类 final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。 2、final方法 如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final 方法。 使用final方法的原因有二: 第一、把方法锁定,防止任何继承类修改它的意义和实现。 第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。 例如:

3、final变量(常量) 用final修饰的成员变量表示常量,值一旦给定就无法改变! final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。 从下面的例子中可以看出,一旦给final变量初值后,值就不能再改变了。 另外,final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final 数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。

super关键字用法

使用super来引用父类的成分,用this来引用当前对象一、super关键字 在JAVA类中使用super来引用父类的成分,用this来引用当前对象,如果一个类从另 外一个类继承,我们new这个子类的实例对象的时候,这个子类对象里面会有一个父类对象。怎么去引用里面的父类对象呢?使用super来引用,this指的是当前对象的引用,super是当前对象里面的父对象的引用。 1.1.super关键字测试 1package cn.galc.test; 2 3/** 4 * 父类 5 * @author gacl 6 * 7*/ 8class FatherClass { 9public int value; 10public void f() { 11 value=100; 12 System.out.println("父类的value属性值="+value); 13 } 14 } 15 16/** 17 * 子类ChildClass从父类FatherClass继承 18 * @author gacl 19 * 20*/ 21class ChildClass extends FatherClass { 22/**

23 * 子类除了继承父类所具有的valu属性外,自己又另外声明了一个value属性, 24 * 也就是说,此时的子类拥有两个value属性。 25*/ 26public int value; 27/** 28 * 在子类ChildClass里面重写了从父类继承下来的f()方法里面的实现,即重写了f()方法的方法体。 29*/ 30public void f() { 31super.f();//使用super作为父类对象的引用对象来调用父类对象里面的f()方法 32 value=200;//这个value是子类自己定义的那个valu,不是从父类继承下来的那个value 33 System.out.println("子类的value属性值="+value); 34 System.out.println(value);//打印出来的是子类自定义的那个value的值,这个值是200 35/** 36 * 打印出来的是父类里面的value值,由于子类在重写从父类继承下来的f()方法时, 37 * 第一句话“super.f();”是让父类对象的引用对象调用父类对象的f()方法, 38 * 即相当于是这个父类对象自己调用f()方法去改变自己的value 属性的值,由0变了100。 39 * 所以这里打印出来的value值是100。 40*/ 41 System.out.println(super.value); 42 } 43 } 44 45/** 46 * 测试类 47 * @author gacl 48 * 49*/ 50public class TestInherit { 51public static void main(String[] args) { 52 ChildClass cc = new ChildClass();

java中如何使用Static的变量和方法

如何使用Static的变量和方法 有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。在成员的声明前面加上关键字static(静态的)就能创建这样的成员。如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static。static 成员的最常见的例子是main( ) 。因为在程序开始执行时必须调用main() ,所以它被声明为static。 声明为static的变量实质上就是全局变量。当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量。声明为static的方法有以下几条限制: 1.它们仅能调用其他的static 方法。 2.它们只能访问static数据。 它们不能以任何方式引用this 或super(关键字super 与继承有关)。 如果你需要通过计算来初始化你的static变量,你可以声明一个static块,Static 块仅在该类被加载时执行一次。下面的例子显示的类有一个static方法,一些static变量,以及一个static 初始化块: // Demonstrate static variables,methods,and blocks. class UseStatic { static int a = 3; static int b; static void meth(int x) { System.out.println("x = " + x); System.out.println("a = " + a); System.out.println("b = " + b); } static { System.out.println("Static block initialized."); b = a * 4; } public static void main(String args[]) { meth(42); } } 一旦UseStatic 类被装载,所有的static语句被运行。首先,a被设置为3,接着static 块执行(打印一条消息),最后,b被初始化为a*4 或12。然后调用main(),main() 调用meth() ,把值42传递给x。3个println ( ) 语句引用两个static变量a和b,以及局部变量x 。 注意:在一个static 方法中引用任何实例变量都是非法的。 下面是该程序的输出: Static block initialized. x = 42 a = 3 b = 12

c++static关键字

C/C++中的static关键字 C/C++中的static有两种用法: 面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类的问题。 A. 面向过程程序设计中的stati c关键字 1) 静态全局变量 在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。静态全局变量定义和使用类似:#include using namespace std; void fn(); static int n; //定义静态全局变量 void main() { n=20; cout< using namespace std; void fn(); void main()

{ fn(); fn(); fn(); } void fn() { static n=10; // 定义了静态局部变量,仅初始化一次! cout << n < using namespace std; static void fn(); //声明静态函数 void main() { fn(); } void fn() //定义静态函数 { int n=10;

Java 中的 static 使用之静态方法

Java 中的static 使用之静态方法 与静态变量一样,我们也可以使用 static 修饰方法,称为静态方法或类方法。其实之前我们一直写的 main 方法就是静态方法。静态方法的使用如: 需要注意: 1、静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。如: 如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。如: 、在普通成员方法中,则可以直接访问同类的非静态变量和静态变量,如下所示:

3、静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法。如: ava 中的static 使用之静态初始化块 Java 中可以通过初始化块进行数据赋值。如: 在类的声明中,可以包含多个初始化块,当创建类的实例时,就会依次执行这些代码块。如果使用 static 修饰初始化块,就称为静态初始化块。 需要特别注意:静态初始化块只在类加载时执行,且只会执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量。 我们来看一段代码:

运行结果: 通过输出结果,我们可以看到,程序运行时静态初始化块最先被执行,然后执行普通初始化块,最后才执行构造方法。由于静态初始化块只在类加载时执行一次,所以当再次创建对象 hello2 时并未执行静态初始化块。 封装 1、概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问 2、好处 a:只能通过规定的方法访问数据 b:隐藏类的实例细节,方便修改和实现。 什么是Java 中的内部类 问:什么是内部类呢? 答:内部类( Inner Class )就是定义在另外一个类里面的类。与之对应,包含内部类的类被称为外部类。 问:那为什么要将一个类定义在另一个类里面呢?清清爽爽的独立的一个类多好啊!! 答:内部类的主要作用如下:

c语言关键字的用法详解

1. Static用法 1.1 static声明的变量在C语言中有两方面的特征: 1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。 2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。 1.2 特点 A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度; B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度; C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题; D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数) E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static 的局部变量的地址作为返回值,若为auto类型,则返回为错指针。 函数前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。 扩展分析:术语static有着不寻常的历史.起初,在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量。随后,static在C中有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。为了避免引入新的关键字,所以仍使用static关键字来表示这第二种含义。最后,C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数(与Java中此关键字的含义相同)。 1.3 关键字static的作用是什么? 这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用:

static和this的理解和用法总结

static和this的理解和用法小结 关键字static和this是初学者比较头疼的知识点,自己也一直比较模糊.现在整理一下,既可以加深自己的印象也可以便于以后查询. 其实在think in java里关于为什么要使用static写的比较详细,不明白的多读几遍会有很大的收获.一般在两钟情形下需要使用static关键字:一种情形是只想用一个存储区域来保存一个特定的数据——无论要创建多少个对象,甚至根本不创建对象。另一种情形是我们需要一个特殊的方法,它没有与这个类的任何对象关联。也就是说,即使没有创建对象,也需要一个能调用的方法。一旦将什么东西设为static,数据或方法就不会同那个类的任何对象实例联系到一起.所以尽管从未创建那个类的一个对象,仍能调用一个static方法,或访问一些static数据。而在这之前,对于非static数据和方法,我们必须创建一个对象,并用那个对象访问数据或方法。这是由于非static数据和方法必须知道它们操作的具体对象.有这样的一个类,其中定义一个静态数据: class Test { Static int i = 47; } Test st1 = new StaticTest();Test st2 = new StaticTest();即使们new了两个Test对象,但它们仍然只占据Test.i的一个存储空间。这两个对象都共享同样的i。对方法来说,static一项重要的用途就是帮助我们在不必创建对象的前提下调用那个方法. 静态变量)一个静态对象属于一个类,但它不属于实例对象,也不是实例对象状态的一部分.每一个静态变量只存在一份.静态变量通常称为类变量(class variable).在实际中,经常需要这样的一个变量,它被一个类的所有实例对象所共享,如果它同时又是公有的,那么它就可以被这个类的任意访问者所使用.静态变量存在于类的作用域之内.通常声明为private.java中许多时候会用到public static final 这样的变量。静态变量可以被位于同一个作用域内的任意方或静态方法访问,访问时使用变量名称即可。如果在类作用域以外访问类,则要使用一个含有类名的表达式访问静态变量,例如: Integer.MAX_VALUE, 其中MAX_VALUE是在类库中声明过的。 静态方法)静态方法或类方法属于一个而不是属于某个实例对象实现的一部分。可以直接通过类来调用这种方法,而并不是只能由某个特定的实例对象调用。静态的方法不能用abstract声明,而且无论是否明确地指定实际上都是final型的。静态方法的声明格式: modifiers static typeName methodName (parameterList){ statementSequence } modifiers(可以从public,protect,private中选择一个),后面可以加上 final,nativc,synchronized中的一个或几个的组合。 static main是静态方法的一个特殊用法,用static main 方法来建立程序的初始状态,创建一组初始对象,并进行合理的方法调用,使得程序能够继续执行下去,static main方法使用String数组型参数包含了用户在运行时给出的任意命令行参数。

java笔记(super关键字的使用)

super 关键字的使用 super 关键字出现在子类中,主要功能就是完成子类调用父类中的内容,也就是调用父类中的属性或方法。 super 调用父类中的构造方法: class Person { String name; int age; public Person(String name,int age) { https://www.360docs.net/doc/c64812196.html,=name; this.age=age; } } class Student extends Person { String school; public Student() { super("张三",27); } } public class TestPersonStudentDemo { public static void main(String args[]) { Student s=new Student(); S.shchool=”北京”; System.out.println("我是:"+https://www.360docs.net/doc/c64812196.html,+",今年:"+s.age+"岁,学校:"+s.school) ; } } 输出结果为:我是张三,今年27岁,学校:北京 本程序在子类的构造方法中明确地指明了调用的是父类中有两个参数的构造方法,所以程序在编译时不再去找父类中无参的构造方法。 用super 调用父类中的构造方法,只能放在子类的第一行。 通过super 调用父类的属性和方法: class Person 父类构造方法 子类构造方法 调用父类构造方法

{ String name; int age; public Person() { } public String talk() { return "我是:"+https://www.360docs.net/doc/c64812196.html,+",今年:"+this.age+"岁"; } } class Student extends Person { String school; public Student(String name,int age,String school) { //在这里用super 调用父类中的属性 https://www.360docs.net/doc/c64812196.html,=name; super.age=age; //调用父类中的talk()方法 System.out.print(super.talk()); //调用本类中属性 this.school=school; } } public class TestPersonStudentDemo3 { public static void main(String args[]) { Student s=new Student("张三",27,"北京"); System.out.println(",学校:"+s.school); } } 输出结果为: 我是:张三,今年:27岁,学校:北京 限制子类的访问 有些时候,父类并不希望子类可以访问自己的类中全部的属性或方法,所以需要将一些属性父类构造方法 子类构造方法 父类一般方法

关于static的用法

关于static的用法: 在《Java编程思想》P86页有这样一段话: “static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。” 这段话虽然只是说明了static方法的特殊之处,但是可以看出static关键字的基本作用,简而言之,一句话来描述就是: 方便在没有创建对象的情况下来进行调用(方法/变量)。 很显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。 static可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。 1)static方法 static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。 但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。举个简单的例子:

在上面的代码中,由于print2方法是独立于对象存在的,可以直接用过类名调用。假如说可以在静态方法中访问非静态方法/变量的话,那么如果在main方法中有下面一条语句: MyObject.print2(); 此时对象都没有,str2根本就不存在,所以就会产生矛盾了。同样对于方法也是一样,由于你无法预知在print1方法中是否访问了非静态成员变量,所以也禁止在静态成员方法中访问非静态成员方法。 而对于非静态成员方法,它访问静态成员方法/变量显然是毫无限制的。 因此,如果说想在不创建对象的情况下调用某个方法,就可以将这个方法设置为static。我们最常见的static方法就是main方法,至于为什么main方法必须是static的,现在就很清楚了。因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。 另外记住,即使没有显示地声明为static,类的构造器实际上也是静态方法。 2)static变量

C语言关键字static

C语言关键字-static 用法1:在一个函数体内使用static定义一个变量,保证该变量只进行一次初始化 例:#include "stdio.h" int test(void) { static int i=0; //对应 int i=0 结果为i=1 i=1 i=1 i=1 i=1 i++; return i; } int main( ) { for(int j=0;j<5;j++) printf("test=%d\n",test()); return 0; } 输出结果:i=1 i=2 i=3 i=4 i=5 用法2:在模块内,函数体外声明的static变量,只能 被模块内函数调用,而模块是无效的(其中模块即:一个.c文件和一个.h文件的结合,其中在STM32单片机

C设计中经常使用)。同样的一个在模块内被声明为static的函数也只能在模块内被其它函数调用,而模块外是无权调用的。一句话总结就是保护一些不能被其它文件访问的全局变量和函数;防止了不同人定义的文件变量名和函数名的重复引起的错误 例://file1.cpp int VarA=0; static int VarB=0; extern void FunB(void) //其中函数前面加extern表示定义为外部函数,其实可以省略,因为C语言默认省略为外部可 //调用 { ; } static int FunA (void) //加了static为静态函数,只能在本模块使用 { int i=0; i++; return i; } //file2.cpp

extern int VarA; //可以 extern int VarB;//错误,为静态变量 extern int FunB;//可以 extern int FunA;//错误,为静态函数 总结:众所周知局部变量在存储方式上可以分为auto (默认的,可省略) static register这3种其中auto 是分配在栈上,占用动态存储空间,在函数调用结束后自动释放;static 分配在静态存储空间,两者的作用域相同,但是生存周期不同,static在所处模块初期初始化一次,其后不再进行初始化,同时如果没有初始化则默认是0或者空字符,但是auto的无初始化的值是随机的数;其中针对C++系统不管是否有static修饰都会调用默认构造函数进行初始化。

静态属性和非静态属性的赋值与取值

public class Test { static int age; //由static修饰,静态属性 int classNum; public static void main(String[] args) { Test person = new Test(); //在这个对象中赋值,12给了classNum,它是非静态属性,所以只在本空间中存在 person.classNum = 12; person.age = 20; //20给了静态属性,也就是说它存在于方法区,所有对象共用 //非静态属性 System.out.println("person中classNum的值:"+ person.classNum);//person中classNum的值:12 System.out.println("person中age的值:" + person.age);//person中age的值:20

Test person2 = new Test(); //因此,在这个新建的空间中,classNum获取不到值,但是age能获取得到20 //非静态属性 System.out.println("person2中classNum的值:" + person2.classNum);//person2中classNum的值:0 System.out.println("person2中age的值:" + person2.age);//person2中age的值:20 } } package com.qianfeng.day07.demo4; public class Pet2 { static int i = 0; /*运用场景: * 1、所有的对象共用某一个属性时,使用静态属性 * 2、跟final 一起使用,可以当常量用 * 3、国际化字符切换*/ public Pet2() { i++; method(); } public static void method() { System.out.println("生成的是第" + i + "个对象");

C++_Static使用

C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。 一、面向过程设计中的static 1、静态全局变量 在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。我们先举一个静态全局变量的例子,如下://Example 1 #include void fn(); static int n; //定义静态全局变量 void main() { n=20; cout<

未经初始化的静态全局变量会被程序自动初始化为0(自动变量的值是随机的,除非它被显式初始化); 静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的; 静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分布情况如下图:代码区 全局数据区 堆区 栈区 一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。细心的读者可能会发现,Example 1中的代码中将 static int n; //定义静态全局变量 改为 int n; //定义全局变量 程序照样正常运行。 的确,定义全局变量就可以实现变量在文件中的共享,但定义静态全局变量还有以下好处: 静态全局变量不能被其它文件所用;

static的作用

static像在VB,C,C++,Java中我们可以看到static最为关键字和函数出现,在其他的高级计算机语言如FORTRAN、ALGOL、COBOL、BASIC、LISP、SNOBOL、PL/1、Pascal、PROLOG、Ada等语 言中也是有出现的,只是有着不同的作用,对于其具体作用,读者有需要的时候是可以具体查阅的鉴 于时间问题今天我就不一一罗列了。 目录 简介 分类 static 函数内部函数和外部函数 当一个源程序由多个源文件组成时,C语言根据函数能否被其它源文件中的函数调用,将函数分为内部函数和外部函数。 内部函数 (又称静态函数) 如果在一个源文件中定义的函数,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用,这种函数称为内部函数。 定义一个内部函数,只需在函数类型前再加一个“static”关键字即可,如下所示: static 函数类型函数名(函数参数表) {……} 关键字“static”,译成中文就是“静态的”,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。

使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。 外部函数 外部函数的定义:在定义函数时,如果没有加关键字“static”,或冠以关键字“extern”,表示此函数是外部函数: [extern] 函数类型函数名(函数参数表) {……} 调用外部函数时,需要对其进行说明: [extern] 函数类型函数名(参数类型表)[,函数名2(参数类型表2)……]; [案例]外部函数应用。 (1)文件mainf.c main() { extern void input(…),process(…),output(…); input(…); process(…); output(…); } (2)文件subf1.c …… extern void input(……) /*定义外部函数*/ {……} (3)文件subf2.c …… extern void process(……) /*定义外部函数*/ {……} (4)文件subf3.c …… extern void output(……) /*定义外部函数*/ {……} C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。 面向过程设计中的static 1、静态全局变量 在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。我们先举一个静态全局变量的例子,如下: //Example 1 #include void fn(); static int n; //定义静态全局变量

static静态变量的理解

C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。(1)先来介绍它的第一条也是最重要的一条:隐藏。 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c。 下面是a.c的内容 char a = 'A'; // global variable void msg() { printf("Hello\n"); } 下面是main.c的内容 int main(void) { extern char a; // extern variable must be declared before use printf("%c ", a); (void)msg(); return 0; } 程序的运行结果是: A Hello 你可能会问:为什么在a.c中定义的全局变量a和函数msg能在main.c中使用?前面说过,所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。此例中,a是全局变量,msg是函数,并且都没有加static 前缀,因此对于另外的源文件main.c是可见的。 如果加了static,就会对其它源文件隐藏。例如在a和msg的定义前加上static,main.c就看不到它们了。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。Static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏,而对于变量,static还有下面两个作用。(2)static的第二个作用是保持变量内容的持久。存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,说到底static还是用来隐藏的。虽然这种用法不常见,但我还是举一个例子。 #include int fun(void){ static int count = 10; // 事实上此赋值语句从来没有执行过 return count--; } int count = 1; int main(void) { printf("global\t\tlocal static\n"); for(; count <= 10; ++count)

相关文档
最新文档