第5章:Java高级类特性4:static_设计模式_代码块_final


时间:2018-07-25 作者:魏文应


一、static 关键字

static 修饰类属性

用static来修饰类的成员变量,也被称为 类变量。我们可以先看下面代码:

class SportsMan{
    String name;
    static String nation;
    
    @Override
    public String toString() {
        return "SportsMan [name=" + name + ", nation=" + nation + "]";
    }
}
public class TestSprotsMan {
    public static void main(String[] args){
        SportsMan s1 = new SportsMan();
        SportsMan s2 = new SportsMan();
        s1.name = "小强";
        s1.nation = "中国";
        System.out.println(s1);
        System.out.println(s2);     
    }
}

输出结果如下:

SportsMan [name=小强, nation=中国]
SportsMan [name=null, nation=中国]

你会发现,s1 和 s2 的 name 属性值不一样,而 nation 属性值是一样的。这说明,static 修饰的成员变量,在由该类创建的所有对象中,static 成员变量,只有一份。假设使用SportsMan类,创建了 s1、s2、s3、s4、s5、s6这些实例,修改任何一个实例的static成员变量,会导致 该类的所有实例 的static成员变量的值发生改变。而 没有 static 修饰 的成员变量,各自有各自的存储单元,不会发生修改实例的成员变量,导致另一个成员变量的值也被修改的情况

  • 内存存储情况

这也说明了,使用 static 修饰的属性,不依赖实例 而存在,只要有类,就有它。所以可以使用 类名.属性 的形式来调用它:

SportsMan.nation = "美国";
System.out.println(SportsMan.nation);

static 修饰类方法

static 修饰的类的方法,也被称为 类方法。和static修饰的类属性一样,类方法有以下特点:

  • 随着类的加载而加载。
  • 内存中也是独有一份。
  • 不依赖类的实例而存在,可以使用 类名.方法 的形式来调用。
  • 内部可以调用 static 修饰的属性和方法。
  • 内部不可以调用 没有 static 修饰的属性和方法。

下面是其应用实例:

class SportsMan{
    static int name;

    public void show(){
        System.out.println("Show:Hello World!");
        show2();        // 类内直接使用
    }

    public static void show2(){
        System.out.println("Show2:Hello World!");
        name = "魏文应";
    }
}
public class TestSprotsMan {
    public static void main(String[] args){
        SportsMan s = new SportsMan();
        s.show();               // 需要创建类的实例

        SportsMan.show2();      // 外面直接调用
    }
}

上面代码中,没有 static 修饰的方法 show() 只能通过 对象.方法 的方式调用,使用该方法前需要创建一个对象。而有 static 修饰的方法 show2() 不但可以使用 对象.方法 的形式调用,还可以使用 类.方法 的形式调用。

二、设计模式

什么是设计模式?就像铁匠,打了一辈子的铁,最后总结了一些经验,这些经验使得打铁更省力,打出的铁性能更好。设计模式也是一样,Java 程序员在必须大量的程序以后,发现了一些比较好的写法,并且这些写法比较常用。将这些写法总结成标准模式,就叫做设计模式。

单例设计模式

什么叫单例模式?单例模式就是有一个类,允许这个类创建一个对象 。下面是一种叫做 饿汉式 单例模式:

class Singleton{
    // 1.私有化构造器,使得类的外部不能够调用此构造器。
    private Singleton(){
    }
    // 2.在类的内部创建一个类的实例
    private static Singleton instance = new Singleton();
    // 3.私有化此对象,通过公共的方法来调用
    public static Singleton getInstance(){
        return instance;
    }
}
public class TestSingleton {
    public static void main(String[] args){
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        System.out.println(s1 == s2);
    }
}

私有化构造器,在类内部创建当前类对象,使用 static 修饰类方法,这样,外部只能通过 类名.方法 的形式返回实例的引用。而这个实例的引用只有一个,那就是 instance ,从而达到这个类只能创建一个实例的效果。另外,还有一种叫做 懒汉式 的单例模式:

class Singleton1{
    private Singleton1(){
        
    }
    private static Singleton1 instance = null;
    public static Singleton1 getInstance(){
        if(instance == null){
            instance = new Singleton1();
        }
        return instance;
    }
}
public class TestSingleton1 {
    public static void main(String[] args){
        Singleton1 s1 = Singleton1.getInstance();
        Singleton1 s2 = Singleton1.getInstance();
        
        System.out.println(s1 == s2);
    }
}

懒汉模式,同样要私有化构造器,类内部在第一次使用 getInstnce 类方法 时,创建一个实例,此后不再创建新的实例。这样的好处是,在需要是在创建实例。缺点是,在多线程中,可能有多个线程进入 if(instance == null) 内部,导致 instance = new Singleton1(); 语句多次被执行。

三、main()方法的使用

在类内部,main方法格式如下:

public static void main(String[] args){
}

它是程序的入口。我们可以对它进行 传参测试

public class TestMain {
    public static void main(String[] args) {
        for(int i = 0; i < args.length; i++){
            System.out.println(args[i]);
        }
    }
}

在 Eclipse 中, 依次点击 Run As -> Run Configurations -> Arguments , 在Program Arguments 中,输入你希望向main() 中传入的参数,比如我这里 传入参数 为三个字符串:

魏文应、小强、宇航
  • main参数输入设置

然后点击 Run 按钮即可。

四、类变量的成员之四:初始化块

什么是初始化块?初始化块就是在一个类中, 用 { } 大括号直接括起来的内容,比如:

class Order{
    {
        System.out.println("我是初始化块");
    }
}

在类中,关于属性的操作,顺序是:

1、先是默认的初始化。
2、显示的初始化或者代码块内初始化。
3、构造器赋值操作。
4、创建对象以后,外部调用赋值操作。

比如,下面对类的属性进行赋值操作:

class Order{
    private int orderId = 1000;
    // 初始化块,非静态代码块
    {
        orderId = 1001;
        System.out.println("我是非静态代码块1");
    }

    {
        orderId = 1002;
        System.out.println("我是非静态代码块2");
    }

    public Order(int orderId) {
        super();
        this.orderId = orderId;
    }

    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }
}
public class TestOrder {
    public static void main(String[] args) {
        Order o1 = new Order(1004);
        System.out.println(o1);
    }
}

首先创建了orderId成员变量,默认初始化 orderId = 0 。然后是我们代码中,显示初始化 orderId = 1000,然后是 代码块 { }orderId = 1001,代码块可以有多个,所以在代码块2中,再次赋值 orderId = 1002 。在然后就是在 构造器中 赋值,最后可以在 外部 赋值。

注意:显式初始化和代码块,它们处于同一优先级别,也就是说,它们在类中出现的先后,是影响赋值的先后的。 比如下面代码:

class Order{
    {
        orderId = 1001;
    }
    private int orderId = 1000;
}

首先 orderId = 0, 然后 orderId = 1001,然后才是 orderId = 1000

static 静态代码块

什么是静态代码块?在类中,使用 static{ } 的代码块。比如下面代码:

class Order{
    static{
        System.out.println("我是静态初始化块");
    }
}

静态代码块的执行,要早于非静态代码块,和在类中的位置无关。注意:静态代码块中,调用的属性和方法都需要是类方法和类属性,也就是static修饰的方法和属性

五、关键字 final

final 表示最终的。可以修饰 属性、方法、类

final 修饰属性

final修饰属性时,赋值以后 值就不可以再修改,相当于常量:

final int PI  = 3.141592563;

既然是常量,那么 final 修饰的成员变量,建议使用 全大写 字母命名。final 修饰的属性,必须显式的赋值。赋值还可以再 代码块、构造器中赋值,但是,赋值操作只能有一次。

class Test{
    final int PI;
    {
        PI  = 3.141592563;
    }
}
class Test{
    final int PI;
    
    public Test(){
        PI  = 3.141592563;
    }
}

final 修饰方法

final 修饰的方法,就不能对它进行重写了:

class Test{
    public final void method1(){    
    }

//  public void method1(){  
//  }
}

比如上面代码,method1() 方法被 final 修饰,那么method1() 方法就 不能再进行重写 了。

final 修饰类

被final 修饰的类,就不能对它进行继承了:

final class Test{
}

那么下面的操作是 不被允许的

class Person extends Test{
}

从上面可以看出,Test 被 final 修饰以后,就 其它类就不能去继承它

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,731评论 2 9
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,573评论 18 399
  • 一、Java 简介 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计...
    子非鱼_t_阅读 4,153评论 1 44
  • 浴血奋战八十春, 党群团结一条心。 东亚睡狮已觉醒, 屹立东方天地新。 2OO1、7、1
    贯华阅读 184评论 4 5
  • #幸福是需要修出来的~每天进步1%~幸福实修09班~09.王文婷 ,银川# 20170719(29/30) 【幸福...
    爱与幸福文婷阅读 184评论 0 2