• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
风吹花落泪如雨
博客园    首页    新随笔    联系   管理    订阅  订阅

JAVA基础(三)-----隐藏和封装,static关键字,初始化块,单例模式

static关键字 

在《Java编程思想》P86页有这样一段话:

  “static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”

这段话虽然只是说明了static方法的特殊之处,但是可以看出static关键字的基本作用,简而言之,一句话来描述就是:

  方便在没有创建对象的情况下来进行调用(方法/变量)。

 

1)static方法

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

2)static变量

  static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

  static成员变量的初始化顺序按照定义的顺序进行初始化。

 

访问控制符

 注意:上述四种访问权限,只有默认访问权限和public能够用来修饰类。修饰类的变量和方法四种权限都可以。(本处所说的类针对的是外部类,不包括内部类)

 

package关键字

package packageName;
javac -d . Hello.java
编译中的 -d选项用于设置编译生成的 class 文件的保存位置. 
这里指定将生成的 class 文件放在当前路径.( . 就代表当前路径) 
使用该命令编译文件后,发现当前路径下并没有 Hello.class 文件. 
而是多了一个名为 lee 的文件夹. 该文件夹下有一个 Hello.class 文件.

import 关键字

如果需要使用不同包中的其它类时, 总是需要使用该类的全名. 
但这是一件很蛋疼的事情. 怎么办呢? 
Java当然为你着想, Java引入了 import 关键字. 
import 可以向某个 Java文件中导入指定包层次下某个类或全部类. 
import 语句应该出现在 package 语句(如果有的话)之后 、 类定义之前. 
一个 Java源文件只能包含一个 package 语句, 但可以包含多个 import 语句. 
多个 import 语句用于导入多个包层次下的类. 
使用 import 语句导入单个类的用法如下:
import package.subpackage...ClassName;

import static关键字

JDK 1.5以后 (现在普遍都使用 JDK1.8或以上版本了 所以肯定支持) 
Java增加了一种静态导入的语法. 
它用于导入指定类的某个静态成员变量 / 方法 / 或全部静态成员变量 / 方法 .
静态导入使用 import static 语句. 
静态导入也有两种语法. 
分别导入指定的类的某个静态成员变量 / 方法 / 或全部静态成员变量 / 方法 
其中导入指定类的单个静态成员变量 / 方法 的语法格式如下:
import static package.subpackage...className.fieldName | mathodName;

 

初始化块

class A {
    static {
        System.out.println("Static init A.");
    }

    {
        System.out.println("Instance init A.");
    }

    A() {
        System.out.println("Constructor A.");
    }
}

class B extends A {
    static {
        System.out.println("Static init B.");
    }

    {
        System.out.println("Instance init B.");
    }

    B() {
        System.out.println("Constructor B.");
    }
}

class C extends B {

    static {
        System.out.println("Static init C.");
    }

    {
        System.out.println("Instance init C.");
    }

    C() {
        System.out.println("Constructor C.");
    }
}

public class Main {

    static {
        System.out.println("Static init Main.");
    }

    {
        System.out.println("Instance init Main.");
    }

    public Main() {
        System.out.println("Constructor Main.");
    }

    public static void main(String[] args) {
        C c = new C();
        //B b = new B();
    }
}

测试代码
View Code
Static init Main.
Static init A.
Static init B.
Static init C.
Instance init A.
Constructor A.
Instance init B.
Constructor B.
Instance init C.
Constructor C.
View Code

观察上面的输出,可以观察到两个有趣的现象:

  1. Main类是肯定没有被实例化过的,但是由于执行main入口函数用到了Main类,于是static初始化块也被执行了;
  2. 所有的静态初始化块都优先执行,其次才是非静态的初始化块和构造函数,它们的执行顺序是:
    1. 父类的静态初始化块
    2. 子类的静态初始化块
    3. 父类的初始化块
    4. 父类的构造函数
    5. 子类的初始化块
    6. 子类的构造函数

 

单例模式

 单例模式有以下特点:

  1、单例类只能有一个实例。
  2、单例类必须自己创建自己的唯一实例。
  3、单例类必须给所有其他对象提供这一实例。

 

class Singleton
{
  //使用一个类变量来缓存曾经创建的实例
  private static Singleton instance;    
  //对构造器使用private修饰,隐藏该构造器
  private Singleton();
  //提供一个静态方法,用于返回Singleton实例
  //该方法可以加入自定义控制,保证只产生一个Singleton对象
  public static Singleton getInstance(){
      //如果instance为null,则表明还不曾创建Singleton对象
      //如果instance不为null,则表明已经创建了Singleton对象
      if(instance == null){
         //创建一个Singleton实例,并将其缓存起来
         instance = new Singleton();
      }
      return instance;
  }      
}
posted @ 2018-06-05 15:59  风吹花落泪如雨  阅读(120)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3