ความหมายของข้อผิดพลาด Android Studio: พารามิเตอร์ที่ไม่มีคำอธิบายประกอบจะแทนที่พารามิเตอร์ @NonNull


104

ฉันกำลังทดลองใช้ Android Studio เมื่อสร้างโปรเจ็กต์ใหม่และเพิ่มonSaveInstanceStateเมธอดเริ่มต้นในคลาสสร้าง MyActivity เมื่อฉันพยายามคอมมิตโค้ดกับ Git ฉันได้รับข้อผิดพลาดแปลก ๆ ที่ฉันไม่เข้าใจ รหัสคือ:

ข้อผิดพลาดที่ฉันได้รับคือ:

ป้อนคำอธิบายภาพที่นี่

ถ้าฉันพยายามเปลี่ยนลายเซ็นวิธีprotected void onSaveInstanceState(@NotNull Bundle outState)เป็น IDE ก็บอกฉันว่ามันไม่สามารถแก้ไขสัญลักษณ์NotNullได้

ฉันต้องทำอย่างไรเพื่อกำจัดคำเตือน

คำตอบ:


124

มันเป็นคำอธิบายประกอบ แต่ชื่อที่ถูกต้องคือNonNull:

protected void onSaveInstanceState(@NonNull Bundle outState)

(และนอกจากนี้ยังมี)

import android.support.annotation.NonNull;

จุดประสงค์คือเพื่อให้คอมไพลเลอร์เตือนเมื่อมีการละเมิดสมมติฐานบางอย่าง (เช่นพารามิเตอร์ของเมธอดที่ควรมีค่าเสมอเช่นในกรณีนี้แม้ว่าจะมีอื่น ๆ ก็ตาม) จากเอกสารประกอบคำอธิบายประกอบการสนับสนุน :

@NonNullคำอธิบายประกอบสามารถนำมาใช้เพื่อบ่งชี้ว่าพารามิเตอร์ที่กำหนดไม่สามารถเป็นโมฆะ

หากทราบว่าตัวแปรโลคัลเป็นโมฆะ (เช่นเนื่องจากโค้ดก่อนหน้านี้บางตัวตรวจสอบว่าเป็นโมฆะหรือไม่) และคุณส่งต่อเป็นพารามิเตอร์ไปยังเมธอดที่พารามิเตอร์นั้นถูกทำเครื่องหมายเป็น @NonNull IDE จะเตือนคุณว่าคุณมี ความผิดพลาดที่อาจเกิดขึ้น

เป็นเครื่องมือสำหรับการวิเคราะห์แบบคงที่ ลักษณะการทำงานของรันไทม์จะไม่เปลี่ยนแปลงเลย


ในกรณีนี้คำเตือนเฉพาะคือเมธอดดั้งเดิมที่คุณกำลังลบล้าง (ในActivity) มี@NonNullคำอธิบายประกอบในoutStateพารามิเตอร์ แต่คุณไม่ได้รวมไว้ในเมธอดการลบล้าง เพียงแค่เพิ่มก็ควรแก้ไขปัญหาได้เช่น

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}

5
จุดประสงค์ของมันคืออะไร?
IgorGanapolsky

2
@IgorGanapolsky ขออภัยไม่ได้กล่าวถึงเรื่องนี้เพราะฉันคิดว่าคำถามเป็นเพียงเกี่ยวกับNotNull/ NonNullความแตกต่าง ปรับคำตอบให้เหมาะสม
matiash

2
กล่าวอีกนัยหนึ่งคือ IMHO คำอธิบายประกอบนี้สามารถลบความจำเป็นของการตรวจสอบค่าว่างภายในฟังก์ชันและมีรหัสที่เร็วกว่า
John Pang

1
@JohnPang คุณทำได้แต่เนื่องจากข้อ จำกัด โดยนัยของคำอธิบายประกอบไม่ได้รับการรับรองว่าจะบังคับใช้จริงจึงอาจไม่ใช่ความคิดที่ดี
matiash

นำเข้า android.support.annotation.NonNull; มองหาสิ่งนี้เป็นเวลา 2 ชั่วโมง ... ไม่มีใครพูดถึงวิธีการนำเข้า NonNull .. จึง
โหวตเพิ่ม

15

เมื่อเร็ว ๆ นี้มีการเพิ่มคำอธิบายประกอบการสนับสนุนที่เป็นประโยชน์จำนวนมากในไลบรารีการสนับสนุนของ Android บทบาทหลักคือการใส่คำอธิบายประกอบคุณสมบัติของวิธีการและพารามิเตอร์ต่างๆเพื่อช่วยในการจับจุดบกพร่อง ตัวอย่างเช่นหากคุณส่งnullค่าไปยังพารามิเตอร์ที่มีเครื่องหมายNotNullคำอธิบายประกอบคุณจะได้รับคำเตือน

คุณสามารถเพิ่มคำอธิบายประกอบลงในโปรเจ็กต์ของคุณด้วย Gradle ได้โดยเพิ่มการอ้างอิงต่อไปนี้:

dependencies {
    compile 'com.android.support:support-annotations:20.0.0'
}

คุณได้รับคำเตือนเนื่องจากBundleพารามิเตอร์ถูกทำเครื่องหมายด้วย@NotNullคำอธิบายประกอบและโดยการแทนที่เมธอดคำอธิบายประกอบจะถูกซ่อน สิ่งที่ควรทำคือเพิ่มคำอธิบายประกอบให้กับพารามิเตอร์ของเมธอด overriden ด้วย

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}

9

นอกเหนือจากคำตอบอื่น ๆ คำอธิบายประกอบ@NonNull(และเป็นของฝ่ายตรงข้าม@Nullable) ยังใส่คำอธิบายประกอบในฟิลด์พารามิเตอร์หรือประเภทการส่งคืนเมธอด IntelliJ และ Android Studio สามารถเตือนคุณได้NullPointerExceptionในเวลาคอมไพล์

ตัวอย่างดีที่สุดที่นี่:

@NonNull private String myString = "Hello";

@Nullable private String myOtherString = null;

@NonNull 
public Object doStuff() {
    System.out.println(myString.length); // No warning
    System.out.println(doSomething(myString).length); // Warning, the result might be null.

    doSomething(myOtherString); // Warning, myOtherString might be null.

    return myOtherString; // Warning, myOtherString might be null.
}

@Nullable
private String doSomething(@NonNull String a) {
    return a.length > 1 ? null : a; // No warning
}

คำอธิบายประกอบเหล่านี้ไม่ได้เปลี่ยนแปลงลักษณะการทำงานของรันไทม์ (แม้ว่าฉันจะทดลองแล้วก็ตาม) แต่ใช้เป็นเครื่องมือในการป้องกันข้อบกพร่อง

โปรดทราบว่าข้อความที่คุณได้รับไม่ใช่ข้อผิดพลาด แต่เป็นเพียงคำเตือนซึ่งปลอดภัยที่จะเพิกเฉยหากคุณเลือก อีกทางเลือกหนึ่งคือใส่คำอธิบายประกอบพารามิเตอร์ด้วยตัวเองตามที่ Android Studio แนะนำ:

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.