• 瑞金千人雨伞拼图创世界吉尼斯纪录 2019-07-02
  • “熊孩子”与幼儿教育 2019-06-15
  • 港媒称中国手游在韩国吸金美日手游遭韩玩家冷落 2019-06-15
  • 酒与植物 轻酌一樽是花香 2019-05-13
  • 台军为帮农民每餐吃香蕉 台媒改善两岸关系是根本 2019-05-12
  • 原脉——大地肌体上的血脉文章中国国家地理网 2019-05-11
  • 用更加过硬的作风追求改革新突破 2019-05-11
  • 欧版T90暴露法德坦克硬伤 VT4我离最强只差两步 2019-05-10
  • 【专题】河北省无偿献血领导小组会议报道 2019-05-10
  • 科幻推理剧《端脑》北京首映 搜狐匠心“烧脑”之作获赞 2019-05-09
  • 【大家谈】激励实干担当,谱写奋斗“进行曲” 2019-05-08
  • 回复@老老保老张工:连马克思都要重构个人所有制也!你不会自以为比马克思还高明吧? 2019-05-08
  • 学习宣传贯彻习近平新时代中国特色社会主义思想系列研讨会br第三场研讨会发言摘编 2019-05-07
  • 2000年出生的孩子属龙,要风得风,要雨得雨 2019-05-07
  • 美国防部宣布暂停8月美韩联合军演 2019-05-06
  • 香港生肖时时彩:为什么java中一切都是对象,还要有static? [复制链接]

    2019-11-13 10:09
    技术小兵 阅读:488 评论:0 赞:1
    Tag:  static

    香港生肖时时彩 www.eptu.com.cn Java是一种面向对象编程的语言,而对象是客观存在的事物,对同类对象抽象出其共性,便是Java中的类,类是对象的模子,具有相同属性和方法的一组对象的集合。有了类的定义,我们就可以用类来描述世上任何东西。然而,有一个特殊的东西不属于对象,它就是static。

    1. static的“由来”

    咱们先来分析一下以下代码:

    public class Demo {
    public static void main(String[] args) {
    //实例化一个p1
    Person p1=new Person();
    p1.name="xiaoming";  
    p1.speak();
    //实例化一个p2
    Person p2=new Person();
    p2.name="xiaohong";  
    p2.speak();
    }
    }

    class Person{
    String name;
    //CN是显示初始化值
    String country="China";
    void speak(){
    System.out.println("My name is "+name+",my country is "+country);
    }
    }

    ??通过分析上面的代码,不难发现p1和p2两个对象中,存在一个相同的属性值country="China"。接下来我们通过内存示意图来观察下:

    为什么java中一切都是对象,还要有static?

      从上图中我们可以注意到红色框中的内容是重复存在于堆中的。倘若对象越建越多,那么堆中的重复数据也会越来越多,这样就会导致内存造成不必要的消耗。既然各个对象中都存在同样的数据,那么何不将这些相同的数据单独拿出来并且单独存放呢?现在将Person类中的country字段加上static,其他不做改动:

    class Person{
    String name;
    //将数据值相同且共用的用static修饰,成为类变量
    static String country="CN"; 
    void speak(){
    System.out.println("My name is "+name+",my country is "+country);
    }
    }

      于是,我们将相同的数据放到静态存储区内,并让静态存储区中的数据共享给所有对象,这样就可以大大减少了不必要的内存损耗,可见static关键字的作用。

    2.static的使用场景

    在《Java编程思想》有这样一段话:
      “static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途?!?br style="-webkit-tap-highlight-color: transparent; box-sizing: border-box;">  这段话虽然只是说明了static方法的特殊之处,但是可以看出static关键字的基本作用,简而言之,一句话来描述就是:方便在没有创建对象的情况下来进行调用(方法/变量)。下面我们就来探讨一下static的几个使用场景。

    1)修饰成员变量和成员方法

    ??用static修饰成员变量可以说是该关键字最常用的一个功能,通常将用static修饰的成员变量称为类成员或者静态成员。本文就是通过该使用场景抛砖引玉,描述了static关键字的“由来”。在jvm的内存构造中,会在堆中开辟一块内存空间,专门用来存储用static修饰的成员变量,称为静态存储区,无论我们创建多少个对象,用 static 修饰的成员变量有且只有一份存储在静态存储区中,所以该静态变量的值是以最后创建对象时设置该静态变量的值为准。并且任何对象都可以对静态存储区中的成员变量做出修改,静态存储区中的成员变量的值以最后一次修改为准。值得一提的是,在JDK1.8以前,静态存储区是存放在方法区的,而方法区不属于堆,在JDK1.8之后,方法区中的静态存储区改为到堆中存储。
      用static修饰方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this指针的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。

    2)静态代码块

    ??静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行,执行顺序为静态代码块—>非静态代码块—>构造方法—>静态方法。我们来运行以下程序:

    Public class Main {
    Static {
    System.out.println(“静态代码块”);
    }
    {
    System.out.println(“非静态代码块”);
    }
    public Main(){
    System.out.println(“构造方法”);
    }
    public static void eat(){
    System.out.println(“静态方法”);
    }
    public static void main(String[] args) {
    Main main = new Main();
    Main.eat();
    }
    }
    运行结果:
    静态代码块
    非静态代码块
    构造方法
    静态方法

    ??而在java继承关系中静态代码块、代码块、构造方法的执行顺序为父类静态代码块—>子类静态代码块—>父类代码块—>父类构造—>子类代码块—>子类构造,可以通过下列代码来判断:

    public class Demo {
    public static void main(String[] args) {
    new H2();
    }
    }
    //父类H1
    class H1{
    {
    System.out.println("父类代码块");
    }
    public H1(){
    System.out.println("父类构造");
    }
    static{
    System.out.println("父类静态代码块");
    }
    }
    //H2继承H1
    class H2 extends H1{
    static{
    System.out.println("子类静态代码块");
    }
    {
    System.out.println("子类代码块");
    }
    public H2(){
    System.out.println("子类构造");
    }
    }
    运行结果:
    父类静态代码块
    子类静态代码块
    父类代码块
    父类构造
    子类代码块
    子类构造

    ??static关键字可以利用这些特性,通过形成静态代码块来优化程序性能。静态代码块可以存在于类的任何一个地方,并且一个类可以有多个静态代码块,在类初次被加载的时候,会按照静态代码块声明的顺序来依此执行,并且只会执行一次。那么,我们就可以利用静态代码块只加载一次的特性,将不需要重复加载的数据放入静态代码块中来优化程序。

    3)静态内部类

    ??内部类指的是定义在一个类的内部的类,包含内部类的类成为外部类,而静态内部类指的是用 static 修饰的内部类。定义内部类的好处是外部类可以访问内部类的所有方法和属性,包括私有方法和私有属性。下面通过代码来理解静态内部类的使用:

    //定义一个普通外部类
    public class OutClass {
    //定义一个普通内部类
    public class InnerClass{

    }
    }

    ??这里我们要想访问普通内部类,就必须先创建外部类的对象,然后通过外部类名.new 创建内部类的实例,例如第一步:OuterClass oc = new OuterClass();第二步:OuterClass.InnerClass in = oc.new InnerClass();。显然,这样的做法不是很友好。

    //定义一个普通外部类
    public class OutClass {
    //定义一个静态内部类
    public static class InnerClass{

    }
    }

    ??如果将普通内部类改为静态内部类,添加static关键字,我们就不需要创建外部类的对象,而是可以直接通过外部类名.内部类名来创建实例,例如OuterClass.InnerClass sic = new OuterClass.InnerClass();。这样就会显得简单很多。

    3.关于static的常见问题

    1)static关键字会改变类中成员的访问权限吗?

    不会。Java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字。

    2)静态变量可以存在于普通方法中吗?

    可以。普通方法必须通过对象来调用,静态变量可以直接通过类名来调用,也可以通过对象来调用,所以是可以存在于普通方法中的。

    3)静态方法能存在普通变量吗?

    不能。因为静态方法可以直接通过类名来直接调用,不用创建对象,而普通变量是必须通过对象来调用的。

    4)static 可以用来修饰局部变量吗?

    不能。在C/C++中static是可以作用域局部变量的,但是在Java中切记:static是不允许用来修饰局部变量。不要问为什么,这是Java语法的规定。

    4.总结

    ??总的来说,static关键字主要作用就是方便在没有创建对象的情况下进行调用方法/变量。当static修饰成员变量和方法时,该变量就成为了所有对象的公共数据,可以直接通过类名来调用而不用创建对象;当static修饰代码块时,该代码块会在类初次被加载的时候被加载,且只会加载一次,这里需要注意加载顺序的问题;当static修饰内部类时,可以使得操作内部类变得想对简单。另外,根据static的特性,产生了一种重要的设计模式——单例设计模式。这里做个简单介绍,程序实例如下:

    class Singleton{
    private static Singleton instance = null;
    private Singleton(){}
    public static getInstance(){
    if(instance == null){
    instance = new Singleton();
    }
    return instance;
    }
    }

    ??单例设计模式的特点是该类只能有一个实例,为了实现这一功能,必须隐藏类的构造函数,即把构造函数声明为private,并提供一个创建对象的方法,由于构造对象被声明为private,外界无法直接创建这个类型的对象,这里就可以把创建对象的方法声明为static,通过使用类名来调用方法创建对象,从而完成该模式的设计


    我来说两句
    您需要登录后才可以评论 登录 | 立即注册
    facelist
    所有评论(0)
    领先的中文移动开发者社区
    18620764416
    7*24全天服务
    意见反?。[email protected]

    扫一扫关注我们

    Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 香港生肖时时彩 )

  • 瑞金千人雨伞拼图创世界吉尼斯纪录 2019-07-02
  • “熊孩子”与幼儿教育 2019-06-15
  • 港媒称中国手游在韩国吸金美日手游遭韩玩家冷落 2019-06-15
  • 酒与植物 轻酌一樽是花香 2019-05-13
  • 台军为帮农民每餐吃香蕉 台媒改善两岸关系是根本 2019-05-12
  • 原脉——大地肌体上的血脉文章中国国家地理网 2019-05-11
  • 用更加过硬的作风追求改革新突破 2019-05-11
  • 欧版T90暴露法德坦克硬伤 VT4我离最强只差两步 2019-05-10
  • 【专题】河北省无偿献血领导小组会议报道 2019-05-10
  • 科幻推理剧《端脑》北京首映 搜狐匠心“烧脑”之作获赞 2019-05-09
  • 【大家谈】激励实干担当,谱写奋斗“进行曲” 2019-05-08
  • 回复@老老保老张工:连马克思都要重构个人所有制也!你不会自以为比马克思还高明吧? 2019-05-08
  • 学习宣传贯彻习近平新时代中国特色社会主义思想系列研讨会br第三场研讨会发言摘编 2019-05-07
  • 2000年出生的孩子属龙,要风得风,要雨得雨 2019-05-07
  • 美国防部宣布暂停8月美韩联合军演 2019-05-06
  • 永利娱乐平台app下载 开元棋牌官网最新版安装 福建快三今天开奖走势图 易发棋牌下载安装 浙江省台州市福彩中心咨询电话 大赢彩票首页 彩票快3模拟器 福建体育彩票36选7走势图 三分彩官网平台彩 山西快乐10分前3走势 股票涨跌百分比怎么看 四川金7乐软件 3d试机号今天晚上金码一一新闻 怎么拍美拍视频赚钱 湖南快乐十分组三追号 新疆十一选五一定牛