成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

java中的一些慣用法總結(jié)

zhangke3016 / 1091人閱讀

摘要:字符串字符串是存儲(chǔ)在字符串常量池中的。面試題假設(shè)字符串常量池中不存在字符串,那么創(chuàng)建了幾個(gè)對(duì)象答兩個(gè)堆空間的值字符數(shù)組和字符串常量池中的實(shí)體。程序運(yùn)行期間,靜態(tài)存儲(chǔ)的數(shù)據(jù)將隨時(shí)等候調(diào)用。中的數(shù)組會(huì)自動(dòng)記性范圍檢查會(huì)造成少量的內(nèi)存開銷。

字符串

字符串是存儲(chǔ)在字符串常量池中的。例如以下的兩個(gè)字符串的內(nèi)存地址值是一樣的:

String str1 = "hello" + "world";
String str2 = "helloworld";
System.out.println(str1 == str2);      // true
System.out.println(str1.equals(str2)); // true

String str3 = "hello";
String str4 = "world";
String str5 = str3 + str4;
System.out.println(str5 == str2);      // false
System.out.println(str5.equals(str2)); // true

在以上的代碼中str2和str5的地址值不相同,如果我們對(duì)str5使用intern()方法即:

String str6 = str5.intern();           // native方法
System.out.println(str6 == str2);      // true

就可以返回true。

面試題:假設(shè)字符串常量池中不存在字符串"hello",那么String s = new String("hello")創(chuàng)建了幾個(gè)對(duì)象?

:兩個(gè)堆空間的value值(字符數(shù)組)和字符串常量池中的hello實(shí)體。我們可以通過查看new String(String str)的源碼:

 /** The value is used for character storage. */
 private final char value[];

 /**
 * Initializes a newly created {@code String} object so that it represents
 * the same sequence of characters as the argument; in other words, the
 * newly created string is a copy of the argument string. Unless an
 * explicit copy of {@code original} is needed, use of this constructor is
 * unnecessary since Strings are immutable.
 *
 * @param  original
 *         A {@code String}
 */
public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}
用句柄操作對(duì)象

java中一切皆對(duì)象,但是我們操作的實(shí)際上是指向這個(gè)對(duì)象的句柄(Handle),這個(gè)句柄也叫做引用(Reference)或者指針(Pointer)。我們可以將這一情形想象成用遙控器(Handler)操作電視機(jī)(Object)。沒有電視機(jī),遙控器。

即使沒有電視機(jī),遙控器也可以多帶帶存在。即句柄是可以多帶帶存在的(并不指向任何實(shí)體)。例如:

String s;

以上的java代碼創(chuàng)建的僅僅是句柄而不是對(duì)象。此時(shí)如果向s發(fā)送一條消息,將會(huì)或者一個(gè)運(yùn)行時(shí)異常,因此更安全的做法是:創(chuàng)建一個(gè)句柄的時(shí)候進(jìn)行顯式初始化:

String s = "";
java程序運(yùn)行時(shí)數(shù)據(jù)的存放位置

Register。處理器內(nèi)部(最快),由于數(shù)量有限,所以寄存器是根據(jù)需要有編譯器分配的。我們對(duì)它沒有直接的控制權(quán),也不可能在程序中找到寄存器的任何蹤跡。

Stack。駐留與常規(guī)RAM區(qū)域,速度僅次于寄存器。我們可以通過它的“堆棧指針”獲得直接的處理支持。(指針下移創(chuàng)建新的內(nèi)存;指針上移釋放內(nèi)存)。創(chuàng)建程序時(shí)java編譯器必須準(zhǔn)確知道堆棧內(nèi)保存的所有數(shù)據(jù)的“長度”以及“存在的時(shí)間”(必須生成相應(yīng)的代碼,以便于向上或者向下移動(dòng)指針)。這一限制無疑影響了程序的靈活性,所以java將對(duì)象的句柄保存在堆棧中,但是對(duì)象并不存放在其中。

Heap。一種常規(guī)用途的內(nèi)存池(也是在RAM區(qū)域),保存java對(duì)象。Heap最吸引人的地方在于:編譯器并不必要知道要從堆中分配多少存儲(chǔ)空間,也不必要知道存儲(chǔ)的數(shù)據(jù)要在堆中停留多長時(shí)間——用堆保存數(shù)據(jù)會(huì)得到更大的靈活性。然而every coin have two slices,在堆中分配存儲(chǔ)空間會(huì)花費(fèi)更長的時(shí)間!

靜態(tài)存儲(chǔ)?!办o態(tài)”(Static)指的是“位于固定位置”。程序運(yùn)行期間,靜態(tài)存儲(chǔ)的數(shù)據(jù)將隨時(shí)等候調(diào)用。我們可以用static關(guān)鍵字指出一個(gè)對(duì)象的特定元素是靜態(tài)的,但是java對(duì)象本身永遠(yuǎn)不會(huì)置入靜態(tài)存儲(chǔ)空間

常數(shù)存儲(chǔ)。常數(shù)存儲(chǔ)通常直接置于一個(gè)程序代碼內(nèi)部。這樣做是安全的,因?yàn)樗麄冇肋h(yuǎn)不會(huì)被改變。有的常數(shù)需要嚴(yán)格保護(hù),可以考慮將他們置入只讀存儲(chǔ)器(ROM)。

非RAM存儲(chǔ):將數(shù)據(jù)完全保存子啊一個(gè)程序之外。對(duì)典型的2個(gè)例子就是“流式對(duì)象”和“固定對(duì)象”。

流式對(duì)象:對(duì)象-->字節(jié)流-->另一臺(tái)機(jī)器

固定對(duì)象:對(duì)象-->磁盤

基本數(shù)據(jù)類型

基本數(shù)據(jù)類型由于比較常用,而堆棧的效率又高于堆。所以基本數(shù)據(jù)類型都是保存在堆棧中。對(duì)于基本數(shù)據(jù)類型我們不需要用new,而是創(chuàng)建了一個(gè)并非句柄的“自動(dòng)變量”,該變量容納了具體的值,并保存在堆中可以更高效的存取。

java中的數(shù)組

在C、C++中使用數(shù)組是非常危險(xiǎn)的,因?yàn)槟切?shù)組只是內(nèi)存塊,如果程序訪問自己內(nèi)存塊之外的數(shù)據(jù)或者在初始化之前使用內(nèi)存會(huì)產(chǎn)生不可預(yù)料的后果。在C++中應(yīng)該盡量避免使用數(shù)組而換用Standard TemplateLibrary中更安全的容器。java中的數(shù)組會(huì)自動(dòng)記性范圍檢查會(huì)造成少量的內(nèi)存開銷。但是我們可以換來更高的工作效率。

變量作用域

變量的作用域是由花括號(hào)的位置決定的。
在C、C++中以下的代碼是合法的:

{
    int x = 10;
    {
        int x = 100; // 不合法Duplicate local variable x
    }
}

但是在java中編譯器會(huì)認(rèn)為變量x已經(jīng)被定義,所以C、C++能將一個(gè)變量“隱藏”在一個(gè)更大的作用域中,java的設(shè)計(jì)者認(rèn)為這樣使程序產(chǎn)生了混淆。

注意區(qū)分成員變量和局部變量

成員變量都有默認(rèn)值,而局部變量必須進(jìn)行初始化。

文檔注釋

文檔注釋只能為public和protected的成員處理文檔,private和default的不會(huì)被javadoc提取。文檔注釋中可以嵌入html,例如:

異常

方法拋出異常的時(shí)候,該方法會(huì)從棧上立即被取出,而異常再度丟給棧上的方法(也就是調(diào)用方),如果調(diào)用方?jīng)]有對(duì)異常進(jìn)行處理而是繼續(xù)拋出異常,調(diào)用方就會(huì)從棧上彈出,異常再度交給此時(shí)的棧頂方法,如此一路下去……
finally中的代碼有一種情況下是執(zhí)行不到的:finally的前面出現(xiàn)了System.exit(0)。

static和final

static只能修飾類的成員(變量和方法),不能修飾局部變量。static變量存放在方法區(qū)。隨著類的加載而加載,存在方法區(qū)中,隨著類的消失而消失,生命周期最長。如果沒有給定初值,static變量會(huì)被默認(rèn)置0.(或者null)。

Q:如果一個(gè)類被標(biāo)記為final,再將該類中的方法標(biāo)記位final是不是很多余?
A:不只是多余,而且是多了很多!如果一個(gè)類為final,那么它根本就沒有子類,根本不可能覆寫父類中的方法(只有繼承才有覆寫)。

使用類加載器加載配置文件

工程目錄如下:

加載該配置文件應(yīng)該這樣寫:

public class Test {

    @org.junit.Test
    public void test() throws IOException {
        
        ClassLoader classLoader = this.getClass().getClassLoader();
        InputStream is = classLoader.getResourceAsStream("org/gpf/conf/db.properties");
        Properties properties = new Properties();
        properties.load(is);
        properties.list(System.out);
    }
}
利用反射獲取父類的泛型
public class Person {
    // some code...
}

public class Student extends Person {
    // some code...
}

Class clazz =  Student.class;
Type type = clazz.getGenericSuperclass(); // org.gpf.Person
ParameterizedType parameterizedType = (ParameterizedType) type; // type的子接口
for (Type c : parameterizedType.getActualTypeArguments()) {
    System.out.println(((Class)c).getName()); // Class是Type接口的實(shí)現(xiàn)類
}
java中的枚舉

所謂枚舉,就是枚舉類的對(duì)象的個(gè)數(shù)是有限的,可以窮舉出來的類。實(shí)際上單例模式也可以使用枚舉來實(shí)現(xiàn)(Effective Java中的單例經(jīng)典實(shí)現(xiàn),枚舉只有一個(gè)成員)。jdk1.5之前需要自定義枚舉類,jdk1.5之后提供了enum關(guān)鍵字用于定義枚舉類。

例如季節(jié)是有限的:春夏秋冬。

// jdk1.5之前的枚舉類
public class Season {

    // 1.聲明final屬性
    
    private final String seasonName;     // 季節(jié)名
    private final String seasonDescribe; // 季節(jié)描述
    
    //  2.為保證實(shí)例的數(shù)目是確定的需要私有化構(gòu)造器,在構(gòu)造器中初始化final的屬性
    private Season(String seasonName,String seasonDescribe) {
        this.seasonName = seasonName;
        this.seasonDescribe = seasonDescribe;
    }

    // 3.通過公用的方法調(diào)用屬性
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDescribe() {
        return seasonDescribe;
    }
    
    // 4.內(nèi)部實(shí)例化枚舉類的對(duì)象
    public static final Season SPRING = new Season("spring", " 春暖花開");
    public static final Season SUMMER = new Season("summer", " 夏日炎炎");
    public static final Season FALL = new Season("fall", " 秋高氣爽");
    public static final Season WINTER = new Season("spring", " 白雪皚皚");

    public String show() {
        return "Season [seasonName=" + seasonName + ", seasonDescribe="
                + seasonDescribe + "]";
    }
    
}

我們可以使用以下的方式進(jìn)行調(diào)用

Season season = Season.FALL;
System.out.println(season.show());
System.out.println(season.getSeasonName() + "-->" + season.getSeasonDescribe());

jdk1.5之后我們可以使用enum關(guān)鍵字來簡化枚舉類的定義:

// jdk1.5之后的枚舉類
public enum Season {

    SPRING("spring", " 春暖花開"),
    SUMMER("summer", " 夏日炎炎"),
    FALL("fall", " 秋高氣爽"),
    WINTER("spring", " 白雪皚皚");
    
    private final String seasonName;     // 季節(jié)名
    private final String seasonDescribe; // 季節(jié)描述
    
    private Season(String seasonName,String seasonDescribe) {
        this.seasonName = seasonName;
        this.seasonDescribe = seasonDescribe;
    }

    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDescribe() {
        return seasonDescribe;
    }
    
    public String show() {
        return "Season [seasonName=" + seasonName + ", seasonDescribe="
                + seasonDescribe + "]";
    }
    
}

這樣使用枚舉類:

Season season = Season.FALL;
System.out.println(season.show());
System.out.println(season.getSeasonName() + "-->" + season.getSeasonDescribe());

Season[] seasons = Season.values(); // 返回所有枚舉類的對(duì)象的數(shù)組
for (Season s : seasons) {
    System.out.println(s.getSeasonName());
}

season = Season.valueOf("SUMMER"); // 返回枚舉類型的對(duì)象
System.out.println(season);

我們也可以讓枚舉類型實(shí)現(xiàn)接口:

// jdk1.5之后的枚舉類
public enum Season implements Info{

    SPRING("spring", " 春暖花開"){
        @Override
        public void show() {
            System.out.println(1);
        }
    },
    SUMMER("summer", " 夏日炎炎"){
        @Override
        public void show() {
            System.out.println(2);
        }
    },
    FALL("fall", " 秋高氣爽"){
        @Override
        public void show() {
            System.out.println(3);
        }
    },
    WINTER("spring", " 白雪皚皚"){
        @Override
        public void show() {
            System.out.println(4);
        }
    };
    
    private final String seasonName;     // 季節(jié)名
    private final String seasonDescribe; // 季節(jié)描述
    
    private Season(String seasonName,String seasonDescribe) {
        this.seasonName = seasonName;
        this.seasonDescribe = seasonDescribe;
    }

    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDescribe() {
        return seasonDescribe;
    }
    
    @Override
    public void show() {
        System.out.println("Season [seasonName=" + seasonName + ", seasonDescribe="
                + seasonDescribe + "]");
    }
    
}

以上的程序中每個(gè)枚舉類型的實(shí)例都各自實(shí)現(xiàn)自己的方法!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64732.html

相關(guān)文章

  • Java 持有對(duì)象(11)

    摘要:如果一個(gè)程序只包含固定數(shù)量且其生命周期都是已知的對(duì)象,那么這是一個(gè)非常簡單的程序。 如果一個(gè)程序只包含固定數(shù)量且其生命周期都是已知的對(duì)象,那么這是一個(gè)非常簡單的程序。 1.泛型和類型安全的容器 通過使用泛型,可以在編譯期防止將錯(cuò)誤類型的對(duì)象放置到容器中. 2.基本概念 Java容器類庫的用途是保存對(duì)象,并將其劃分為兩個(gè)不同的概念:Collection,Map. Collection...

    summerpxy 評(píng)論0 收藏0
  • Java編程思想》筆記11.持有對(duì)象

    摘要:迭代器通常被成為輕量級(jí)對(duì)象創(chuàng)建它的代價(jià)很小。與迭代器可以用于數(shù)組和所有對(duì)象,之所以能夠工作,是因?yàn)槔^承了接口。 點(diǎn)擊進(jìn)入我的博客 我覺得本章名字改成容器似乎更好理解,持有對(duì)象讓人感到一頭霧水我們需要在任意時(shí)刻和任意位置創(chuàng)建任意數(shù)量的對(duì)象,所以依靠創(chuàng)建命名的引用來持有對(duì)象已經(jīng)滿足不了需求。Java可以用數(shù)組和其他容器類來(List、Set、Queue、Map)來解決這個(gè)問題,不同的容器...

    newtrek 評(píng)論0 收藏0
  • js中的立即執(zhí)行函數(shù)

    摘要:匿名函數(shù)的好處在于可以減少局部變量,以免污染現(xiàn)有的運(yùn)行環(huán)境。另外通過,這三個(gè)符號(hào)運(yùn)行的匿名函數(shù)比運(yùn)行的匿名函數(shù)可以減少一個(gè)字符的使用但是我們通常使用加因?yàn)槠渌牟僮鞣赡軙?huì)帶來其他的影響更多可以參考 js中的立即執(zhí)行函數(shù) ( function(){…} )()和( function (){…} () )是兩種javascript立即執(zhí)行函數(shù)的常見寫法 問題: 為什么會(huì)出現(xiàn)上面的兩種不一...

    zhunjiee 評(píng)論0 收藏0
  • Javascript知識(shí)點(diǎn):IIFE - 立即調(diào)用函數(shù)

    摘要:所以那些匿名函數(shù)附近使用括號(hào)或一些一元運(yùn)算符的慣用法,就是來引導(dǎo)解析器,指明運(yùn)算符附近是一個(gè)表達(dá)式。 Immediately-invoked Function Expression(IIFE,立即調(diào)用函數(shù)),簡單的理解就是定義完成函數(shù)之后立即執(zhí)行。因此有時(shí)候也會(huì)被稱為自執(zhí)行的匿名函數(shù)(self-executing anonymous function)。 IIFE的叫法最早見于Ben...

    goji 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<