編譯器空指針
⑴ 空指針錯誤是什麼意思
所謂的空指針異常,就是一個指針是空指針,你還要去操作它,既然它指向的是空對象,它就不能使用這個對象的方法。比如上面的s假如為null,你還要用s的方法,比如s.equals( String x);那麼就會產生空指針異常。
產生空指針異常的原因:
(1) 當一個對象不存在時又調用其方法會產生異常 obj.method() // obj對象不存在
(2) 當訪問或修改一個對象不存在的欄位時會產生異常 obj.method() // method方法不存在
(1)編譯器空指針擴展閱讀:
空指針正常工作意義:
在許多語言,這不是一個單獨的轉義序列,而是八進制轉義序列,單個八進制數字為0;因此,『 』不能跟隨任何數字0通過7;否則它被解釋為更長的八進制轉義序列的開始。被在使用中發現各種語言的其他轉義序列 00,x00,z,或的Unicode表示u0000。
表示空字元的能力並不總是意味著生成的字元串將被正確解釋,因為許多程序將認為null作為字元串的結尾。因此,鍵入它的能力(在未經檢查的用戶輸入的情況下)會創建一個稱為空位元組注入的漏洞,並可能導致安全漏洞。
空字元以逗號表示是^@。在Windows上,可以通過按住Ctrl鍵,然後按@(這通常需要同時按下⇧ Shift並按下數字2鍵)。
參考資料:網路——空指針
⑵ 怎樣在程序里獲得一個空指針
根據語言定義, 在指針上下文中的常數 0 會在編譯時轉換為空指針。也就是
說, 在初始化、賦值或比較的時候, 如果一邊是指針類型的值或表達式, 編譯器可
以確定另一邊的常數 0 為空指針並生成正確的空指針值。因此下邊的代碼段完全
合法:
char *p = 0;
if(p != 0)
然而, 傳入函數的參數不一定被當作指針環境, 因而編譯器可能不能識別未加修飾的 0 「表示」 指針。在函數調用的上下文中生成空指針需要明確的類型轉換,強制把 0 看作指針。例如, Unix 系統調用 execl 接受變長的以空指針結束的字元指針參數。它應該如下正確調用:
execl("/bin/sh", "sh", "-c", "date", (char *)0);
如果省略最後一個參數的 (char *) 轉換, 則編譯器無從知道這是一個空指針,從而當作一個 0 傳入。
如果范圍內有函數原型, 則參數傳遞變為 「賦值上下文」, 從而可以安全省略多數類型轉換, 因為原型告知編譯器需要指針, 使之把未加修飾的 0 正確轉換為適當的指針。函數原型不能為變長參數列表中的可變參數提供類型。在函數調用時對所有的空指針進行類型轉換可能是預防可變參數和無原型函數出問題的最安全的辦法。
⑶ c語言為什麼在本地空指針用的了,到了網教編譯器卻提示空指針沒有定義,把NULL改成『\0』就可以了
NULL需要包含stdio.h
如果你沒有包含stdio.h 那麼使用NULL會報錯.
另外,根據你的描述, 改成\0即可. 而\0 是char型.NULL是void *型.
所以很可能是你賦值類型錯誤,將NULL賦值給了char變數, 本地編譯忽略了類型轉換.
網教的更加嚴格,不允許指針賦值給字元型.
⑷ C語言為什麼在本地空指針用的了,到了網教編譯器卻提示空指針沒有定義,把NULL改成『\0』就可以了
怎麼說呢,這個是我個人見解,如有不對請各位指點
對於指針在本地使用,操作系統要干很多事情,對於程序來說虛擬內存是關系最密切的,因此,每一個變數都是有意義,有根可尋的。當不進行指針初始化的話,很可能是一個野指針,操縱系統不會答應的。而網路編程發送的是數據流,他是寫到buff裡面的。你沒有必要寫一個0X0000 0000,畢竟寫一個'\0'對面可以解析出來這個數據內容為0X0000 0000,這樣不但省空間,而且表達的意思沒有二義性,你覺得選擇那個更好呢?
⑸ java中的空指針異常怎麼解決
原文:https://www.hu.com/question
你這個問題的解決
問題定位:
在堆棧異常信息的第一行就可以定位到是哪裡出了空指針,倘若這里不是你寫的類,可以往下翻一下,找到你寫的類,就是這里出現的空指針。
問題解決:
對一個空對象調用裡面的方法或者屬性的時候會報空指針,檢查這個對象為什麼是空即可。
Java 空指針異常的若干解決方案
Java 中任何對象都有可能為空,當我們調用空對象的方法時就會拋出 NullPointerException 空指針異常,這是一種非常常見的錯誤類型。我們可以使用若干種方法來避免產生這類異常,使得我們的代碼更為健壯。本文將列舉這些解決方案,包括傳統的空值檢測、編程規范、以及使用現代 Java 語言引入的各類工具來作為輔助。
運行時檢測
最顯而易見的方法就是使用 if (obj == null) 來對所有需要用到的對象來進行檢測,包括函數參數、返回值、以及類實例的成員變數。當你檢測到 null 值時,可以選擇拋出更具針對性的異常類型,如 IllegalArgumentException,並添加消息內容。我們可以使用一些庫函數來簡化代碼,如 Java 7 開始提供的 Objects#requireNonNull 方法:
public void testObjects(Object arg) {
Object checked = Objects.requireNonNull(arg, "arg must not be null");
checked.toString();}
Guava 的 Preconditions 類中也提供了一系列用於檢測參數合法性的工具函數,其中就包含空值檢測:
public void testGuava(Object arg) {
Object checked = Preconditions.checkNotNull(arg, "%s must not be null", "arg");
checked.toString();
}
我們還可以使用 Lombok 來生成空值檢測代碼,並拋出帶有提示信息的空指針異常:
public void testLombok(@NonNull Object arg) {
arg.toString();
生成的代碼如下:
public void testLombokGenerated(Object arg) {
if (arg == null) {
throw new NullPointerException("arg is marked @NonNull but is null");
}
arg.toString();
}
這個註解還可以用在類實例的成員變數上,所有的賦值操作會自動進行空值檢測。
編程規范
·通過遵守某些編程規范,也可以從一定程度上減少空指針異常的發生。
使用那些已經對 null 值做過判斷的方法,如 String#equals、String#valueOf、以及三方庫中用來判斷字元串和集合是否為空的函數:
if (str != null && str.equals("text")) {}
if ("text".equals(str)) {}
if (obj != null) { obj.toString(); }
String.valueOf(obj); // "null"
// from spring-core
StringUtils.isEmpty(str);
CollectionUtils.isEmpty(col);
// from guava
Strings.isNullOrEmpty(str);
// from commons-collections4
CollectionUtils.isEmpty(col);
·如果函數的某個參數可以接收 null 值,考慮改寫成兩個函數,使用不同的函數簽名,這樣就可以強制要求每個參數都不為空了:
public void methodA(Object arg1) {
methodB(arg1, new Object[0]);
}
public void methodB(Object arg1, Object[] arg2) {
for (Object obj : arg2) {} // no null check
}
·如果函數的返回值是集合類型,當結果為空時,不要返回 null 值,而是返回一個空的集合;如果返回值類型是對象,則可以選擇拋出異常。Spring JdbcTemplate 正是使用了這種處理方式:
// 當查詢結果為空時,返回 new ArrayList<>()
jdbcTemplate.queryForList("SELECT * FROM person");
// 若找不到該條記錄,則拋出
jdbcTemplate.queryForObject("SELECT age FROM person WHERE id = 1", Integer.class);
// 支持泛型集合
public <T> List<T> testReturnCollection() {
return Collections.emptyList();
}
靜態代碼分析
Java 語言有許多靜態代碼分析工具,如 Eclipse IDE、SpotBugs、Checker Framework 等,它們可以幫助程序員檢測出編譯期的錯誤。結合 @Nullable 和 @Nonnull 等註解,我們就可以在程序運行之前發現可能拋出空指針異常的代碼。
但是,空值檢測註解還沒有得到標准化。雖然 2006 年 9 月社區提出了 JSR 305 規范,但它長期處於擱置狀態。很多第三方庫提供了類似的註解,且得到了不同工具的支持,其中使用較多的有:
javax.annotation.Nonnull:由 JSR 305 提出,其參考實現為 com.google.code.findbugs.jsr305;
org.eclipse.jdt.annotation.NonNull:Eclipse IDE 原生支持的空值檢測註解;
e.umd.cs.findbugs.annotations.NonNull:SpotBugs 使用的註解,基於 findbugs.jsr305;
org.springframework.lang.NonNull:Spring Framework 5.0 開始提供;
org.checkerframework.checker.nullness.qual.NonNull:Checker Framework 使用;
android.support.annotation.NonNull:集成在安卓開發工具中;
- <dependency>
- <groupId>com.github.spotbugs</groupId>
- <artifactId>spotbugs-annotations</artifactId>
- <version>3.1.7</version>
- </dependency>
- @NonNull
- private Object returnNonNull() {
- // 錯誤:returnNonNull() 可能返回空值,但其已聲明為 @Nonnull
- return null;
- }
- @CheckForNull
- private Object returnNullable() {
- return null;
- }
- public void testReturnNullable() {
- Object obj = returnNullable();
- // 錯誤:方法的返回值可能為空
- System.out.println(obj.toString());
- }
- private void argumentNonNull(@NonNull Object arg) {
- System.out.println(arg.toString());
- }
- public void testArgumentNonNull() {
- // 錯誤:不能將 null 傳遞給非空參數
- argumentNonNull(null);
- }
- public void testNullableArgument(@CheckForNull Object arg) {
- // 錯誤:參數可能為空
- System.out.println(arg.toString());
- }
- import org.checkerframework.checker.nullness.qual.Nullable;
- @Nullable
- private Object returnNullable() {
- return null;
- }
- public void testReturnNullable() {
- Object obj = returnNullable();
- // 錯誤:obj 可能為空
- System.out.println(obj.toString());
- }
- private Object returnNonNull() {
- // 錯誤:方法聲明為 @NonNull,但返回的是 null。
- return null;
- }
- private void argumentNonNull(Object arg) {
- System.out.println(arg.toString());
- }
- public void testArgumentNonNull() {
- // 錯誤:參數聲明為 @NonNull,但傳入的是 null。
- argumentNonNull(null);
- }
- // 這是 spring-core 中定義的類和方法
- public abstract class StringUtils {
- // str 參數繼承了全局的 @NonNull 註解
- public static String capitalize(String str) {}
- @Nullable
- public static String getFilename(@Nullable String path) {}
- }
- // 錯誤:參數聲明為 @NonNull,但傳入的是 null。
- StringUtils.capitalize(null);
- String filename = StringUtils.getFilename("/path/to/file");
- // 錯誤:filename 可能為空。
- System.out.println(filename.length());
- Optional<String> opt;
- // 創建
- opt = Optional.empty();
- opt = Optional.of("text");
- opt = Optional.ofNullable(null);
- // 判斷並讀取
- if (opt.isPresent()) {
- opt.get();
- }
- // 默認值
- opt.orElse("default");
- opt.orElseGet(() -> "default");
- opt.orElseThrow(() -> new NullPointerException());
- // 相關操作
- opt.ifPresent(value -> {
- System.out.println(value);
- });
- opt.filter(value -> value.length() > 5);
- opt.map(value -> value.trim());
- opt.flatMap(value -> {
- String trimmed = value.trim();
- return trimmed.isEmpty() ? Optional.empty() : Optional.of(trimmed);
- });
- String zipCode = getUser()
- .flatMap(User::getAddress)
- .flatMap(Address::getZipCode)
- .orElse("");
- stringList.stream().findFirst().orElse("default");
- stringList.stream()
- .max(Comparator.naturalOrder())
- .ifPresent(System.out::println);
- val opt: Option[String] = Some("text")
- opt.getOrElse("default")
- opt match {
- case Some(text) => println(text)
- case None => println("default")
- opt.map(_.trim).filter(_.length > 0).map(_.toUpperCase).getOrElse("DEFAULT")
- val upper = for {
- text <- opt
- trimmed <- Some(text.trim())
- upper <- Some(trimmed) if trimmed.length > 0
- } yield upper
- upper.getOrElse("DEFAULT")
- var a: String = "text"
- a = null // 錯誤:無法將 null 賦值給非空 String 類型。
- val b: String? = "text"
- // 錯誤:操作可空類型時必須使用安全操作符(?.)或強制忽略(!!.)。
- println(b.length)
- val l: Int? = b?.length // 安全操作
- b!!.length // 強制忽略,可能引發空值異常
我建議使用一種跨 IDE 的解決方案,如 SpotBugs 或 Checker Framework,它們都能和 Maven 結合得很好。
SpotBugs 與 @NonNull、@CheckForNull
SpotBugs 是 FindBugs 的後繼者。通過在方法的參數和返回值上添加 @NonNull 和 @CheckForNull 註解,SpotBugs 可以幫助我們進行編譯期的空值檢測。需要注意的是,SpotBugs 不支持 @Nullable 註解,必須用 @CheckForNull 代替。如官方文檔中所說,僅當需要覆蓋 @ParametersAreNonnullByDefault 時才會用到 @Nullable。
官方文檔 中說明了如何將 SpotBugs 應用到 Maven 和 Eclipse 中去。我們還需要將 spotbugs-annotations 加入到項目依賴中,以便使用對應的註解。
以下是對不同使用場景的說明:
對於 Eclipse 用戶,還可以使用 IDE 內置的空值檢測工具,只需將默認的註解 org.eclipse.jdt.annotation.Nullable 替換為 SpotBugs 的註解即可:

Checker Framework 與 @NonNull、@Nullable
Checker Framework 能夠作為 javac 編譯器的插件運行,對代碼中的數據類型進行檢測,預防各類問題。我們可以參照 官方文檔,將 Checker Framework 與 maven-compiler-plugin 結合,之後每次執行 mvn compile 時就會進行檢查。Checker Framework 的空值檢測程序支持幾乎所有的註解,包括 JSR 305、Eclipse、甚至 lombok.NonNull。
Checker Framework 默認會將 @NonNull 應用到所有的函數參數和返回值上,因此,即使不添加這個註解,以下程序也是無法編譯通過的:
Checker Framework 對使用 Spring Framework 5.0 以上的用戶非常有用,因為 Spring 提供了內置的空值檢測註解,且能夠被 Checker Framework 支持。一方面我們無需再引入額外的 Jar 包,更重要的是 Spring Framework 代碼本身就使用了這些註解,這樣我們在調用它的 API 時就能有效地處理空值了。舉例來說,StringUtils 類里可以傳入空值的函數、以及會返回空值的函數都添加了 @Nullable 註解,而未添加的方法則繼承了整個框架的 @NonNull 註解,因此,下列代碼中的空指針異常就可以被 Checker Framework 檢測到了:
Optional 類型
Java 8 引入了 Optional<T> 類型,我們可以用它來對函數的返回值進行包裝。這種方式的優點是可以明確定義該方法是有可能返回空值的,因此調用方必須做好相應處理,這樣也就不會引發空指針異常。但是,也不可避免地需要編寫更多代碼,而且會產生很多垃圾對象,增加 GC 的壓力,因此在使用時需要酌情考慮。
方法的鏈式調用很容易引發空指針異常,但如果返回值都用 Optional 包裝起來,就可以用 flatMap 方法來實現安全的鏈式調用了:
Java 8 Stream API 同樣使用了 Optional 作為返回類型:
此外,Java 8 還針對基礎類型提供了單獨的 Optional 類,如 OptionalInt、OptionalDouble 等,在性能要求比較高的場景下很適用。
其它 JVM 語言中的空指針異常
Scala 語言中的 Option 類可以對標 Java 8 的 Optional。它有兩個子類型,Some 表示有值,None 表示空。
除了使用 Option#isEmpty 判斷,還可以使用 Scala 的模式匹配:
Scala 的集合處理函數庫非常強大,Option 則可直接作為集合進行操作,如 filer、map、以及列表解析(for-comprehension):
Kotlin 使用了另一種方式,用戶在定義變數時就需要明確區分 可空和不可空類型。當可空類型被使用時,就必須進行空值檢測。
Kotlin 的特性之一是與 Java 的可互操作性,但 Kotlin 編譯器無法知曉 Java 類型是否為空,這就需要在 Java 代碼中使用註解了,而 Kotlin 支持的 註解 也非常廣泛。Spring Framework 5.0 起原生支持 Kotlin,其空值檢測也是通過註解進行的,使得 Kotlin 可以安全地調用 Spring Framework 的所有 API。
結論
在以上這些方案中,我比較推薦使用註解來預防空指針異常,因為這種方式十分有效,對代碼的侵入性也較小。所有的公共 API 都應該使用 @Nullable 和 @NonNull 進行註解,這樣就能強制調用方對空指針異常進行預防,讓我們的程序更為健壯。
⑹ 懇求各位Java同學,看看我這段代碼到底是哪裡出現了空指針異常 編譯器一直拋出空指針異常啊!謝謝各位
ImageIcon image=new ImageIcon(getClass().getResource("image.png"));
image.png圖片沒有
應該把圖片放在和這個類的同一個目錄下。。
不可以是別的地方,必須是同一個目錄下。。
由getClass().getResource("image.png")決定的
⑺ c語言 出現空指針賦值怎麼回事請高手幫忙看下。
是編譯器報的空指針賦值吧?主要原因:作者沒有搞清楚C中的全局變數和局部變數的問題。
1。zts[35];point1[35];point2[35];x1[35]這四個數組在main()中有,在四個子函數中有,各是各的,互不幹涉,所以main()中的這四個數組始終沒有被賦值過,空指針指的就是這個吧。
2。應該把這四個數組的首地址作為四個read()的參數傳過去,就可以實現:「在子函數中賦值,在main函數中使用」 的設計目的了。看程序,感覺作者就是這個目的吧。
3。 魔尊8 說的有一定道理,這四個read確實沒有起到應有的作用。加上數組首地址做參數就可以了。或者把這四個數組做成全局變數也行啊。
4。作者有時間的話還是應該好好看看C語言的書啊。
⑻ 關於java中空指針異常
空指針異常產生的主要原因如下:
(1)當一個對象不存在時又調用其方法會產生異常obj.method() // obj對象不存在
(2)當訪問或修改一個對象不存在的欄位時會產生異常obj.method() // method方法不存在
(3)字元串變數未初始化;
(4)介面類型的對象沒有用具體的類初始化,比如:
List lt;會報錯
List lt = new ArrayList();則不會報錯了
當一個對象的值為空時,你沒有判斷為空的情況。你可以試著把下面的代碼前加一行代碼:
if(rb!=null && rb!="")
改成:
if(rb==null);
if(rb!==null&&rb!="") 或者if((「」).equals(rb))
空指針的解決辦法:
重點關注報錯發生的所在行,通過空指針異常產生的兩條主要原因診斷具體的錯誤。同時為了避免空指針的發生,最好在做判斷處理時將「null」或者空值放於設定的值之前。
⑼ C++中如何定義空指針
在C++11(C++0x)里,空指針有了一個官方版的表示:nullptr。
一種方法是定義一個NULL宏(#defineNULL0)來表示空指針,雖然本質上和直接寫成0一樣,但NULL能相對直觀地表示這是個指針。
一些知名頭文件里就帶有NULL的定義,比如windows.h和stdio.h。直接用NULL似乎是個不錯的主意。
有時候源文件中並不需要引用到這些知名頭文件,那麼NULL就要由自己來定義。
另外,NULL可以由自己定義,這意味著NULL完全有可能被定義成其他東西(少見)。因為NULL並非標准,所以有人可能自己定義了Null或null或其他東西(少見),這會帶來混亂。
那麼直接用0來表示空指針好了。用0表示寫起來簡單,而且0就是0,不會有其他定義,只是不那麼直觀。
(9)編譯器空指針擴展閱讀:
當通過指針來訪問指針所指向的內存區時,指針所指向的類型決定了編譯器將把那片內存區里的內容當做什麼來看待。從語法上看,只須把指針聲明語句中的指針名字和名字左邊的指針聲明符*去掉,剩下的就是指針所指向的類型。例如:
int*ptr;//指針所指向的類型是int
char*ptr;//指針所指向的的類型是char
int**ptr;//指針所指向的的類型是int*
int(*ptr)[3];//指針所指向的的類型是int()[3]
int*(*ptr)[4];//指針所指向的的類型是int*()[4]
⑽ C++函數指針和空指針的問題
函數int plus(int b)的指針類型原型為:int (*)(int)
其中左側int指定函數返回類型,右側(int)表示函數的參數類型。指針類型定義中,凡是右側有括弧的都表示是個函數指針,而括弧內可以定義0個或多個參數,以逗號分隔。中間的(*)把星號獨立起來表示是個指針定義。
當要直接定義一個函數指針時將變數名放星號後面,比如這樣:
int (*p)(int) =NULL;
雙參數定義:int (*p)(int,int) =NULL;
圖例中由於pV是個虛指針(萬能指針),可以賦值任意類型的地址,因此pV=Plus不會報錯,但訪問時必須強轉,否則編譯器不知道如何訪問指針(強轉就是將指定類型放在變數左側,比如(int)a就是將a的值強轉為int類型),強轉格式:(類型) 變數 ,那麼外面要套一層括弧:(int (*)(int))pV,我們需要用強轉後的函數指針傳遞參數進行函數調用,為避免歧義,因此需要連同變數名再打包一次:((int (*)(int))pV),隨後再傳遞參數10:
((int (*)(int))pV)(10)
括弧打包的內容可以看作一個整體/對象,你迷惑的主要因素應該有兩點:
1、不知道如何定義函數指針類型。
實際上就是將函數定義中的函數名用(*)替換,再將參數名去掉就可以了,比如下面這個函數
int * Fun(int a,char c){。。。。。。}
其函數指針類型為: int * (*)(int,char)
指針定義:int* (*p)(int, char);
2、括弧嵌套多了看起來比較亂。這個很簡單,一層一層拆解一層層理解。