Java NullPointerException - Zbuloni, rregulloni dhe praktikat më të mira


java.lang.NullPointerException është një nga aplikacionet më të njohura në ueb Java.

java.lang.NullPointerException

NullPointerException është një përjashtim i kohës së ekzekutimit, kështu që ne nuk kemi nevojë ta kapim atë në program. NullPointerException ngrihet në një aplikacion kur ne po përpiqemi të bëjmë një operacion në null ku kërkohet një objekt. Disa nga arsyet e zakonshme për NullPointerException në programet java janë:

  1. Thirrja e një metode në një shembull objekti por në kohën e ekzekutimit objekti është i pavlefshëm.
  2. Qasja në variablat e një shembulli objekti që është i pavlefshëm në kohën e ekzekutimit.
  3. Hedhja e pavlefshme në program
  4. Qasja në indeks ose modifikimi i vlerës së një indeksi të një grupi që është null
  5. Kontrollimi i gjatësisë së një grupi që është i pavlefshëm në kohën e ekzekutimit.

Shembuj Java NullPointerException

Le të shohim disa shembuj të NullPointerException në programet java.

1. NullPointerException kur thirret një metodë shembulli

public class Temp {

	public static void main(String[] args) {

		Temp t = initT();
		
		t.foo("Hi");
		
	}

	private static Temp initT() {
		return null;
	}

	public void foo(String s) {
		System.out.println(s.toLowerCase());
	}
}

Kur ekzekutojmë programin e mësipërm, ai nxjerr mesazhin e mëposhtëm të gabimit NullPointerException.

Exception in thread "main" java.lang.NullPointerException
	at Temp.main(Temp.java:7)

Ne po marrim NullPointerException në deklaratën t.foo(Hi); sepse \t këtu është e pavlefshme.

2. Java NullPointerException gjatë qasjes/modifikimit të fushës së një objekti null

public class Temp {

	public int x = 10;
	
	public static void main(String[] args) {

		Temp t = initT();
		
		int i = t.x;
		
	}

	private static Temp initT() {
		return null;
	}

}

Programi i mësipërm hedh gjurmën e stivës së mëposhtme NullPointerException.

Exception in thread "main" java.lang.NullPointerException
	at Temp.main(Temp.java:9)

NullPointerException po hidhet në deklaratën int i=t.x; sepse \t” këtu është e pavlefshme.

3. Java NullPointerException kur null kalohet në argumentin e metodës

public class Temp {

	public static void main(String[] args) {

		foo(null);

	}

	public static void foo(String s) {
		System.out.println(s.toLowerCase());
	}
}

Kjo është një nga dukuritë më të zakonshme të java.lang.NullPointerException sepse është thirrësi ai që kalon argumentin null.

Imazhi i mëposhtëm tregon përjashtimin e treguesit null kur programi i mësipërm ekzekutohet në Eclipse IDE.

4. java.lang.NullPointerException kur hidhet null

public class Temp {

	public static void main(String[] args) {

		throw null;
	}

}

Më poshtë është gjurma e pirgut të përjashtimit të programit të mësipërm, që tregon NullPointerException për shkak të deklaratës throw null; .

Exception in thread "main" java.lang.NullPointerException
	at Temp.main(Temp.java:5)

5. NullPointerException kur merrni gjatësinë e grupit null

public class Temp {

	public static void main(String[] args) {

		int[] data = null;
		
		int len = data.length;
	}

}
Exception in thread "main" java.lang.NullPointerException
	at Temp.main(Temp.java:7)

6. NullPointerException kur qaseni në vlerën e indeksit të grupit null

public class Temp {

	public static void main(String[] args) {

		int[] data = null;
		
		int len = data[2];
	}

}
Exception in thread "main" java.lang.NullPointerException
	at Temp.main(Temp.java:7)

7. NullPointerException kur sinkronizohet në një objekt null

public class Temp {

	public static String mutex = null;
	
	public static void main(String[] args) {

		synchronized(mutex) {
			System.out.println("synchronized block");
		}		
	}
}

sinkronizuar(mutex) do të hedhë NullPointerException sepse objekti \mutex” është i pavlefshëm.

8. Statusi HTTP 500 java.lang.NullPointerException

Ndonjëherë marrim një përgjigje faqeje gabimi nga një aplikacion ueb Java me një mesazh gabimi si \Statusi HTTP 500 – Gabim i brendshëm i serverit dhe shkaku kryesor si java.lang.NullPointerException.

Për këtë, unë redaktova projektin Spring MVC Example dhe ndryshova metodën HomeController si më poshtë.

@RequestMapping(value = "/user", method = RequestMethod.POST)
	public String user(@Validated User user, Model model) {
		System.out.println("User Page Requested");
		System.out.println("User Name: "+user.getUserName().toLowerCase());
		System.out.println("User ID: "+user.getUserId().toLowerCase());
		model.addAttribute("userName", user.getUserName());
		return "user";
	}

Imazhi i mëposhtëm tregon mesazhin e gabimit të hedhur nga përgjigja e aplikacionit në internet.

Këtu është gjurma e pirgut të përjashtimit:

HTTP Status 500 – Internal Server Error

Type Exception Report

Message Request processing failed; nested exception is java.lang.NullPointerException

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
	org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause

java.lang.NullPointerException
	com.journaldev.spring.controller.HomeController.user(HomeController.java:38)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.lang.reflect.Method.invoke(Method.java:498)

Shkaku kryesor është NullPointerException në deklaratën user.getUserId().toLowerCase() sepse user.getUserId() po kthehet null.

Si të zbuloni java.lang.NullPointerException

Zbulimi i NullPointerException është shumë i lehtë, thjesht shikoni gjurmën e përjashtimit dhe do t'ju tregojë emrin e klasës dhe numrin e rreshtit të përjashtimit. Pastaj shikoni kodin dhe shikoni se çfarë mund të jetë null që shkakton NullPointerException. Vetëm shikoni të gjithë shembujt e mësipërm, është shumë e qartë nga gjurmimi i stivës se çfarë po shkakton përjashtimin e treguesit null.

Si të rregulloni NullPointerException

java.lang.NullPointerException është një përjashtim i pakontrolluar, kështu që ne nuk kemi pse ta kapim atë. Përjashtimet e treguesit null mund të parandalohen duke përdorur kontrolle të pavlefshme dhe teknika kodimi parandalues. Shikoni shembujt e kodit më poshtë që tregojnë se si të shmangni java.lang.NullPointerException.

if(mutex ==null) mutex =""; //preventive coding
		
synchronized(mutex) {
	System.out.println("synchronized block");
}
//using null checks
if(user!=null && user.getUserName() !=null) {
System.out.println("User Name: "+user.getUserName().toLowerCase());
}
if(user!=null && user.getUserName() !=null) {
	System.out.println("User ID: "+user.getUserId().toLowerCase());
}

Kodimi i praktikave më të mira për të shmangur NullPointerException

1. Le të shqyrtojmë funksionin e mëposhtëm dhe të shikojmë për skenarin që shkakton përjashtim të treguesit null.

public void foo(String s) {
    if(s.equals("Test")) {
	System.out.println("test");
    }
}

NullPointerException mund të ndodhë nëse argumenti kalohet si null. E njëjta metodë mund të shkruhet si më poshtë për të shmangur NullPointerException.

public void foo(String s) {
	if ("Test".equals(s)) {
		System.out.println("test");
	}
}

2. Mund të shtojmë gjithashtu kontroll null për argument dhe të hedhim IllegalArgumentException nëse kërkohet.

public int getArrayLength(Object[] array) {
	
	if(array == null) throw new IllegalArgumentException("array is null");
	
	return array.length;
}

3. Ne mund të përdorim operator tresh siç tregohet në kodin e shembullit më poshtë.

String msg = (str == null) ? "" : str.substring(0, str.length()-1);

4. Përdorni metodën String.valueOf() në vend të toString() . Për shembull, kontrolloni PrintStream println() kodi i metodës është përcaktuar si më poshtë.

public void println(Object x) {
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);
            newLine();
        }
    }

Pjesa e mëposhtme e kodit tregon shembullin ku përdoret metoda valueOf() në vend të toString().

Object mutex = null;

//prints null
System.out.println(String.valueOf(mutex));

//will throw java.lang.NullPointerException
System.out.println(mutex.toString());

5. Shkruani metoda që kthejnë objekte boshe dhe jo null kudo që të jetë e mundur, për shembull, listë boshe, varg bosh, etj.

6. Ka disa metoda të përcaktuara në klasat e mbledhjes për të shmangur NullPointerException, duhet t'i përdorni ato. Për shembull përmban(), containKey(), dhe containValue().

Referenca: Dokumenti API