代碼錯誤java空指針 java空指針是什么意思

Java 空指針報錯

說明 你的代碼在 MainUI.java類有的255行有一個空指針錯誤,你看看是不是 有一個對象類型的變量 沒有賦值或者調用其他方法所得的值為空、間接地他就為空了,所以就報錯了。檢查一下,你的255行是在哪里,你調用的那個方法。

在鑲黃等地區(qū),都構建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供網站建設、成都網站制作 網站設計制作按需定制制作,公司網站建設,企業(yè)網站建設,高端網站設計,營銷型網站,外貿網站制作,鑲黃網站建設費用合理。

java代碼里邊調用怎么會報空指針異常

空指針異常產生的主要原因如下:itjob網上有例子,

(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!==nullrb!="") 或者if((“”).equals(rb))

空指針的解決辦法:

重點關注報錯發(fā)生的所在行,通過空指針異常產生的兩條主要原因診斷具體的錯誤。同時為了避免空指針的發(fā)生,最好在做判斷處理時將“null”或者空值放于設定的值之前。

java中的空指針異常怎么解決

原文:

你這個問題的解決

問題定位:

在堆棧異常信息的第一行就可以定位到是哪里出了空指針,倘若這里不是你寫的類,可以往下翻一下,找到你寫的類,就是這里出現(xiàn)的空指針。

問題解決:

對一個空對象調用里面的方法或者屬性的時候會報空指針,檢查這個對象為什么是空即可。

Java 空指針異常的若干解決方案

Java 中任何對象都有可能為空,當我們調用空對象的方法時就會拋出 NullPointerException 空指針異常,這是一種非常常見的錯誤類型。我們可以使用若干種方法來避免產生這類異常,使得我們的代碼更為健壯。本文將列舉這些解決方案,包括傳統(tǒng)的空值檢測、編程規(guī)范、以及使用現(xiàn)代 Java 語言引入的各類工具來作為輔助。

運行時檢測

最顯而易見的方法就是使用 if (obj == null) 來對所有需要用到的對象來進行檢測,包括函數(shù)參數(shù)、返回值、以及類實例的成員變量。當你檢測到 null 值時,可以選擇拋出更具針對性的異常類型,如 IllegalArgumentException,并添加消息內容。我們可以使用一些庫函數(shù)來簡化代碼,如 Java 7 開始提供的 Objects#requireNonNull 方法:

public void testObjects(Object arg) {

Object checked = Objects.requireNonNull(arg, "arg must not be null");

checked.toString();}

Guava 的 Preconditions 類中也提供了一系列用于檢測參數(shù)合法性的工具函數(shù),其中就包含空值檢測:

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();

}

這個注解還可以用在類實例的成員變量上,所有的賦值操作會自動進行空值檢測。

編程規(guī)范

·通過遵守某些編程規(guī)范,也可以從一定程度上減少空指針異常的發(fā)生。

使用那些已經對 null 值做過判斷的方法,如 String#equals、String#valueOf、以及三方庫中用來判斷字符串和集合是否為空的函數(shù):

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);

·如果函數(shù)的某個參數(shù)可以接收 null 值,考慮改寫成兩個函數(shù),使用不同的函數(shù)簽名,這樣就可以強制要求每個參數(shù)都不為空了:

public void methodA(Object arg1) {

methodB(arg1, new Object[0]);

}

public void methodB(Object arg1, Object[] arg2) {

for (Object obj : arg2) {} // no null check

}

·如果函數(shù)的返回值是集合類型,當結果為空時,不要返回 null 值,而是返回一個空的集合;如果返回值類型是對象,則可以選擇拋出異常。Spring JdbcTemplate 正是使用了這種處理方式:

// 當查詢結果為空時,返回 new ArrayList()

jdbcTemplate.queryForList("SELECT * FROM person");

// 若找不到該條記錄,則拋出 EmptyResultDataAccessException

jdbcTemplate.queryForObject("SELECT age FROM person WHERE id = 1", Integer.class);

// 支持泛型集合

public T ListT testReturnCollection() {

return Collections.emptyList();

}

靜態(tài)代碼分析

Java 語言有許多靜態(tài)代碼分析工具,如 Eclipse IDE、SpotBugs、Checker Framework 等,它們可以幫助程序員檢測出編譯期的錯誤。結合 @Nullable 和 @Nonnull 等注解,我們就可以在程序運行之前發(fā)現(xiàn)可能拋出空指針異常的代碼。

但是,空值檢測注解還沒有得到標準化。雖然 2006 年 9 月社區(qū)提出了 JSR 305 規(guī)范,但它長期處于擱置狀態(tài)。很多第三方庫提供了類似的注解,且得到了不同工具的支持,其中使用較多的有:

javax.annotation.Nonnull:由 JSR 305 提出,其參考實現(xiàn)為 com.google.code.findbugs.jsr305;

org.eclipse.jdt.annotation.NonNull:Eclipse IDE 原生支持的空值檢測注解;

edu.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:集成在安卓開發(fā)工具中;

我建議使用一種跨 IDE 的解決方案,如 SpotBugs 或 Checker Framework,它們都能和 Maven 結合得很好。

SpotBugs 與 @NonNull、@CheckForNull

SpotBugs 是 FindBugs 的后繼者。通過在方法的參數(shù)和返回值上添加 @NonNull 和 @CheckForNull 注解,SpotBugs 可以幫助我們進行編譯期的空值檢測。需要注意的是,SpotBugs 不支持 @Nullable 注解,必須用 @CheckForNull 代替。如官方文檔中所說,僅當需要覆蓋 @ParametersAreNonnullByDefault 時才會用到 @Nullable。

官方文檔 中說明了如何將 SpotBugs 應用到 Maven 和 Eclipse 中去。我們還需要將 spotbugs-annotations 加入到項目依賴中,以便使用對應的注解。

dependency

groupIdcom.github.spotbugs/groupId

artifactIdspotbugs-annotations/artifactId

version3.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 傳遞給非空參數(shù)

argumentNonNull(null);

}

public void testNullableArgument(@CheckForNull Object arg) {

// 錯誤:參數(shù)可能為空

System.out.println(arg.toString());

}

對于 Eclipse 用戶,還可以使用 IDE 內置的空值檢測工具,只需將默認的注解 org.eclipse.jdt.annotation.Nullable 替換為 SpotBugs 的注解即可:

Checker Framework 與 @NonNull、@Nullable

Checker Framework 能夠作為 javac 編譯器的插件運行,對代碼中的數(shù)據類型進行檢測,預防各類問題。我們可以參照 官方文檔,將 Checker Framework 與 maven-compiler-plugin 結合,之后每次執(zhí)行 mvn compile 時就會進行檢查。Checker Framework 的空值檢測程序支持幾乎所有的注解,包括 JSR 305、Eclipse、甚至 lombok.NonNull。

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());

}

Checker Framework 默認會將 @NonNull 應用到所有的函數(shù)參數(shù)和返回值上,因此,即使不添加這個注解,以下程序也是無法編譯通過的:

private Object returnNonNull() {

// 錯誤:方法聲明為 @NonNull,但返回的是 null。

return null;

}

private void argumentNonNull(Object arg) {

System.out.println(arg.toString());

}

public void testArgumentNonNull() {

// 錯誤:參數(shù)聲明為 @NonNull,但傳入的是 null。

argumentNonNull(null);

}

Checker Framework 對使用 Spring Framework 5.0 以上的用戶非常有用,因為 Spring 提供了內置的空值檢測注解,且能夠被 Checker Framework 支持。一方面我們無需再引入額外的 Jar 包,更重要的是 Spring Framework 代碼本身就使用了這些注解,這樣我們在調用它的 API 時就能有效地處理空值了。舉例來說,StringUtils 類里可以傳入空值的函數(shù)、以及會返回空值的函數(shù)都添加了 @Nullable 注解,而未添加的方法則繼承了整個框架的 @NonNull 注解,因此,下列代碼中的空指針異常就可以被 Checker Framework 檢測到了:

// 這是 spring-core 中定義的類和方法

public abstract class StringUtils {

// str 參數(shù)繼承了全局的 @NonNull 注解

public static String capitalize(String str) {}

@Nullable

public static String getFilename(@Nullable String path) {}

}

// 錯誤:參數(shù)聲明為 @NonNull,但傳入的是 null。

StringUtils.capitalize(null);

String filename = StringUtils.getFilename("/path/to/file");

// 錯誤:filename 可能為空。

System.out.println(filename.length());

Optional 類型

Java 8 引入了 OptionalT 類型,我們可以用它來對函數(shù)的返回值進行包裝。這種方式的優(yōu)點是可以明確定義該方法是有可能返回空值的,因此調用方必須做好相應處理,這樣也就不會引發(fā)空指針異常。但是,也不可避免地需要編寫更多代碼,而且會產生很多垃圾對象,增加 GC 的壓力,因此在使用時需要酌情考慮。

OptionalString opt;

// 創(chuàng)建

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);

});

方法的鏈式調用很容易引發(fā)空指針異常,但如果返回值都用 Optional 包裝起來,就可以用 flatMap 方法來實現(xiàn)安全的鏈式調用了:

String zipCode = getUser()

.flatMap(User::getAddress)

.flatMap(Address::getZipCode)

.orElse("");

Java 8 Stream API 同樣使用了 Optional 作為返回類型:

stringList.stream().findFirst().orElse("default");

stringList.stream()

.max(Comparator.naturalOrder())

.ifPresent(System.out::println);

此外,Java 8 還針對基礎類型提供了單獨的 Optional 類,如 OptionalInt、OptionalDouble 等,在性能要求比較高的場景下很適用。

其它 JVM 語言中的空指針異常

Scala 語言中的 Option 類可以對標 Java 8 的 Optional。它有兩個子類型,Some 表示有值,None 表示空。

val opt: Option[String] = Some("text")

opt.getOrElse("default")

除了使用 Option#isEmpty 判斷,還可以使用 Scala 的模式匹配:

opt match {

case Some(text) = println(text)

case None = println("default")

Scala 的集合處理函數(shù)庫非常強大,Option 則可直接作為集合進行操作,如 filer、map、以及列表解析(for-comprehension):

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")

Kotlin 使用了另一種方式,用戶在定義變量時就需要明確區(qū)分 可空和不可空類型。當可空類型被使用時,就必須進行空值檢測。

var a: String = "text"

a = null // 錯誤:無法將 null 賦值給非空 String 類型。

val b: String? = "text"

// 錯誤:操作可空類型時必須使用安全操作符(?.)或強制忽略(!!.)。

println(b.length)

val l: Int? = b?.length // 安全操作

b!!.length // 強制忽略,可能引發(fā)空值異常

Kotlin 的特性之一是與 Java 的可互操作性,但 Kotlin 編譯器無法知曉 Java 類型是否為空,這就需要在 Java 代碼中使用注解了,而 Kotlin 支持的 注解 也非常廣泛。Spring Framework 5.0 起原生支持 Kotlin,其空值檢測也是通過注解進行的,使得 Kotlin 可以安全地調用 Spring Framework 的所有 API。

結論

在以上這些方案中,我比較推薦使用注解來預防空指針異常,因為這種方式十分有效,對代碼的侵入性也較小。所有的公共 API 都應該使用 @Nullable 和 @NonNull 進行注解,這樣就能強制調用方對空指針異常進行預防,讓我們的程序更為健壯。

新聞標題:代碼錯誤java空指針 java空指針是什么意思
標題鏈接:http://www.muchs.cn/article4/doeeiie.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供關鍵詞優(yōu)化搜索引擎優(yōu)化、微信小程序、網站改版網站營銷、網站導航

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

外貿網站制作