java 定義長(zhǎng)度為0的數(shù)組/空數(shù)組案例
如下:
int[] array = new int[0]; // 定義一個(gè)長(zhǎng)度為 0 的數(shù)組 / 空數(shù)組 Sring[] arr = new String[0]; // 定義一個(gè)長(zhǎng)度為 0 的數(shù)組 / 空數(shù)組
長(zhǎng)度為 0 的數(shù)組 / 空數(shù)組 并不是 null
有時(shí)數(shù)組里可能只有一個(gè)空字符串 "",這時(shí)數(shù)組長(zhǎng)度是 1。這種情況也要注意判斷。
if ( arr.length == 1 && arr[ 0 ].equals( "" ) ) { System.out.println( "輸入的數(shù)組不能只包含一個(gè)空字符串" ); return; }
補(bǔ)充:java定義一個(gè)空數(shù)組_一個(gè) Java 方法,最多能定義多少參數(shù)?
在 JVM 中,一個(gè) Java 方法,最多能定義多少參數(shù)呢?這是一個(gè)很無(wú)聊的問(wèn)題,即使能定義一萬(wàn)個(gè),十萬(wàn)個(gè),誰(shuí)又會(huì)真的去這么做呢。
但是作為一個(gè) coder,最重要的不就是好奇心嗎,沒(méi)有好奇心,和一條咸魚(yú)又有什么區(qū)別呢?本文作者就是這樣一位充滿好奇心的 coder。
我最近給我的 QuickTheories 分支添加了一個(gè)接口:
@FunctionalInterface public interface QuadFunction { E apply(A a, B b, C c, D d); }
讓我好奇的是這個(gè)方法能有多少個(gè)類型參數(shù)。到目前為止,我敢說(shuō),Java 語(yǔ)言規(guī)范并沒(méi)有談及這個(gè)問(wèn)題。
對(duì)于實(shí)現(xiàn)定義的限制可能是什么,我有兩個(gè)猜測(cè):
1、編譯器會(huì)設(shè)置一個(gè)可預(yù)測(cè)的限制,如 255 或 65535。
2、編譯器的緊急行為會(huì)由于實(shí)現(xiàn)細(xì)節(jié)(堆棧溢出或同樣不可預(yù)測(cè)/不相關(guān)的東西)而設(shè)置意外的限制。
我不想在源代碼上測(cè)試我那點(diǎn)可憐的 C++技巧,所以我決定只測(cè)試編譯器做了什么。我寫(xiě)了一個(gè) Python 腳本,它使用二進(jìn)制搜索找到最少的致錯(cuò)類型參數(shù)。完整的腳本放在 Github repo (https://github.com/hyperpape/java-max-type-params) 中。
腳本地址:https://github.com/hyperpape/java-max-type-params
生成方法很簡(jiǎn)單。幸運(yùn)的是,我們不必使用任何類型參數(shù),只需以的形式發(fā)出它們:
def write_type_plain(count): with open('Test.java', 'w') as f: f.write("public class Test {\n") f.write("public for i in range(count): if (i > 0): f.write(", ") f.write("A" + str(i + 1)) f.write("> void testMethod() {}") f.write("}")
運(yùn)行二進(jìn)制搜索可以得到以下輸出:
>>> error: UTF8 representation for string ">>> largest type: 2776
這個(gè)錯(cuò)誤有點(diǎn)模糊,但事后看來(lái)是可以預(yù)見(jiàn)的。編譯器生成的類文件包含許多字符串,包括類中每個(gè)方法的方法簽名。這些字符串存儲(chǔ)在常量池中,常量池中的條目最大為 65535 字節(jié),這是由 JVM 規(guī)范規(guī)定的限制。
所以,我之前的猜測(cè)都不完全正確。類型參數(shù)的最大數(shù)目是一個(gè)突現(xiàn)特征(emergent property),而不是一個(gè)明確的決定。不過(guò),并不是編譯器本身的實(shí)現(xiàn)導(dǎo)致了錯(cuò)誤。
相反,JVM 的類文件格式限制了可以在類文件中表示的類型參數(shù)的數(shù)量。這是真的,盡管 JVM對(duì)泛型一無(wú)所知。這也意味著類型參數(shù)的最大數(shù)目完全取決于如何編寫(xiě)方法。
我嘗試了一種新的編碼類型參數(shù)的方法(先前鏈接文件中的 write_Type_Compact),使用完整的合法 ASCII 字符(A-Z、a-z、$和_)。該實(shí)現(xiàn)有點(diǎn)過(guò)于復(fù)雜,因?yàn)榭梢允褂米址?0~9,但不能是標(biāo)識(shí)符的初始字符,因?yàn)?Java 關(guān)鍵字不能作為類型參數(shù)出現(xiàn)。我只是用等長(zhǎng)的 UTF-8 字符替換了短單詞「if」和「do」。更緊湊的編碼將參數(shù)數(shù)量從 2776 增加到 3123。
不方便的是,_A 是一種合法的 Java 標(biāo)識(shí)符,但 _ 不是。謝天謝地,我的編碼在不使用初始_情況下就生成了 3392 個(gè) 2 字節(jié)類型參數(shù),因此我覺(jué)得沒(méi)有必要進(jìn)行簿記以發(fā)出初始字符_。
再來(lái)一個(gè)小技巧
解壓類文件顯示,65536 個(gè)字符的大部分不是我生成的類型參數(shù),而是子字符串 Ljava/lang/object 的重復(fù)實(shí)例。因?yàn)闆](méi)有提供關(guān)于類型參數(shù)的信息,所以類文件顯示它們擴(kuò)展了對(duì)象,并在方法簽名中對(duì)其進(jìn)行編碼。我修改了生成器來(lái)解決這個(gè)問(wèn)題。
循環(huán)的關(guān)鍵部分是:
s = type_var(i) f.write(s) if (s != 'A'): f.write(" extends A")
在類型參數(shù)中,除了一個(gè)實(shí)例 java/Lang/Object 之外的所有實(shí)例都被替換為 A。在進(jìn)行了這個(gè)更改之后,編譯了一個(gè)具有 9851 個(gè)類型參數(shù)的方法。
由于參數(shù)的數(shù)量增加了很多,所以我使用的代碼肯定需要調(diào)整。使用非 ASCII Unicode 標(biāo)識(shí)符可能是完全高效的必要條件,但簡(jiǎn)單地指出這是可以做到的我就很滿意了。
這些都不重要
很難想象有人會(huì)達(dá)到這個(gè)極限。代碼生成有時(shí)會(huì)達(dá)到語(yǔ)言或編譯器的限制,但即使生成的代碼似乎也不太可能使用成百上千的類型參數(shù)。
盡管如此,如果我是規(guī)則制定者,我會(huì)考慮明確禁止任何類或方法具有 255 個(gè)以上的類型參數(shù)。明確的限制似乎更好,即使它只影響百萬(wàn)分之一的程序。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
- java使用數(shù)組和鏈表實(shí)現(xiàn)隊(duì)列示例
- java數(shù)組算法例題代碼詳解(冒泡排序,選擇排序,找最大值、最小值,添加、刪除元素等)
- Java基礎(chǔ)語(yǔ)法之二維數(shù)組詳解
- Java基礎(chǔ)之?dāng)?shù)組超詳細(xì)知識(shí)總結(jié)
- Java基礎(chǔ)之?dāng)?shù)組模擬循環(huán)隊(duì)列
- Java 自定義動(dòng)態(tài)數(shù)組方式
- 詳細(xì)總結(jié)Java堆棧內(nèi)存、堆外內(nèi)存、零拷貝淺析與代碼實(shí)現(xiàn)
- 深入了解Java虛擬機(jī)棧以及內(nèi)存模型
- 使用java一維數(shù)組模擬壓棧彈棧
- Java 利用棧來(lái)反轉(zhuǎn)鏈表和排序的操作
- Java棧的三種實(shí)現(xiàn)方式(完整版)
- Java異常日志堆棧丟失的原因與排查
- 教你怎么用Java數(shù)組和鏈表實(shí)現(xiàn)棧
相關(guān)文章
教你利用SpringBoot寫(xiě)一個(gè)屬于自己的Starter
如果我們將可獨(dú)立于業(yè)務(wù)代碼之外的功配置模塊封裝成一個(gè)個(gè)starter,復(fù)用的時(shí)候只需要將其在pom中引用依賴即可,SpringBoot為我們完成自動(dòng)裝配,簡(jiǎn)直不要太爽,這篇文章主要給大家介紹了關(guān)于如何利用SpringBoot寫(xiě)一個(gè)屬于自己的Starter,需要的朋友可以參考下2022-03-03Java中類與對(duì)象的相關(guān)知識(shí)點(diǎn)總結(jié)
對(duì)象是類實(shí)例化出來(lái)的,對(duì)象中含有類的屬性,類是對(duì)象的抽象,下面這篇文章主要給大家介紹了關(guān)于Java中類與對(duì)象的一些相關(guān)知識(shí)點(diǎn),需要的朋友可以參考下2021-11-11Springboot微服務(wù)打包Docker鏡像流程解析
這篇文章主要介紹了Springboot微服務(wù)打包Docker鏡像流程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08解決java使用axios.js的post請(qǐng)求后臺(tái)時(shí)無(wú)法接收到入?yún)⒌膯?wèn)題
今天小編就為大家分享一篇解決java使用axios.js的post請(qǐng)求后臺(tái)時(shí)無(wú)法接收到入?yún)⒌膯?wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09Java將對(duì)象寫(xiě)入文件讀出_序列化與反序列化的實(shí)例
下面小編就為大家?guī)?lái)一篇Java將對(duì)象寫(xiě)入文件讀出_序列化與反序列化的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08