Maison  >  Article  >  Java  >  Comment gérer l'exception de pointeur nul en Java

Comment gérer l'exception de pointeur nul en Java

WBOY
WBOYavant
2023-05-10 17:43:061748parcourir

NullPointerException est l'exception la plus courante dans le code Java. Je classe ses scénarios les plus probables dans les 5 types suivants :

  • La valeur du paramètre est un type d'empaquetage tel que Integer. Lorsqu'elle est utilisée, une exception de pointeur nul se produit en raison du déballage automatique.

  • Une exception de pointeur nul se produit lors de la comparaison de chaînes ;

  • Les conteneurs tels que ConcurrentHashMap ne prennent pas en charge que la clé et la valeur soient nulles, et forcer une clé ou une valeur nulle entraînera une exception de pointeur nul ; l'objet contient B , après avoir obtenu B via les champs de l'objet A, une exception de pointeur nul se produit lors de la mise en cascade de la méthode de B sans vérifier le champ ; la Liste renvoyée par la méthode ou le service distant n'est pas vide mais nulle, et la Liste est appelé directement sans vérifier la valeur null. Une exception de pointeur null s'est produite dans la méthode.

  • private List<String> wrongMethod(FooService fooService, Integer i, String s, String t) {
        log.info("result {} {} {} {}", i + 1, s.equals("OK"), s.equals(t),
                new ConcurrentHashMap<String, String>().put(null, null));
        if (fooService.getBarService().bar().equals("OK"))
            log.info("OK");
        return null;
    }
    
    @GetMapping("wrong")
    public int wrong(@RequestParam(value = "test", defaultValue = "1111") String test) {
        return wrongMethod(test.charAt(0) == &#39;1&#39; ? null : new FooService(),
                test.charAt(1) == &#39;1&#39; ? null : 1,
                test.charAt(2) == &#39;1&#39; ? null : "OK",
                test.charAt(3) == &#39;1&#39; ? null : "OK").size();
    }
    
    class FooService {
        @Getter
        private BarService barService;
    
    }
    
    class BarService {
        String bar() {
            return "OK";
        }
    }

    L'idée de réparation est la suivante :

Pour le jugement nul d'Integer, vous pouvez utiliserOptional.ofNullable pour construire un facultatif, puis utiliser orElse(0) pour remplacer null par la valeur par défaut, puis effectuer l'opération +1. Pour une comparaison entre String et littéral, vous pouvez mettre le littéral devant, tel que "OK".equals(s), de sorte que même si s est nul, une exception de pointeur nul ne se produira pas et pour deux variables de chaîne qui peuvent l'être ; null Pour une comparaison égale, vous pouvez utiliser Objects.equals, qui effectuera un traitement nul.

  • Pour ConcurrentHashMap, puisque ni sa clé ni sa valeur ne prennent en charge null, le correctif consiste à ne pas y stocker null. La clé et la valeur de HashMap peuvent être stockées dans null, tandis que ConcurrentHashMap semble être une version thread-safe de HashMap, mais elle ne prend pas en charge la clé et la valeur de valeur null. C'est un endroit où des malentendus sont faciles à se produire.

  • Pour les appels en cascade comme fooService.getBarService().bar().equals("OK"), il existe de nombreux endroits où null doit être vérifié, y compris les valeurs de retour des méthodes fooService et getBarService() , et les valeurs de retour de la méthode bar string. Si vous utilisez if-else pour vérifier null, vous aurez peut-être besoin de plusieurs lignes de code, mais si vous utilisez Facultatif, une ligne de code suffit.

  • Pour la liste renvoyée par rightMethod, puisqu'il est impossible de confirmer si elle est nulle, avant d'appeler la méthode size pour obtenir la taille de la liste, vous pouvez également utiliserOptional.ofNullable pour envelopper la valeur de retour, puis transmettre .orElse (Collections.emptyList()) L'implémentation obtient une liste vide lorsque la liste est nulle et appelle enfin la méthode size.

  • private List<String> rightMethod(FooService fooService, Integer i, String s, String t) {
        log.info("result {} {} {} {}", Optional.ofNullable(i).orElse(0) + 1, "OK".equals(s), Objects.equals(s, t), new HashMap<String, String>().put(null, null));
        Optional.ofNullable(fooService)
                .map(FooService::getBarService)
                .filter(barService -> "OK".equals(barService.bar()))
                .ifPresent(result -> log.info("OK"));
        return new ArrayList<>();
    }
    
    @GetMapping("right")
    public int right(@RequestParam(value = "test", defaultValue = "1111") String test) {
        return Optional.ofNullable(rightMethod(test.charAt(0) == &#39;1&#39; ? null : new FooService(),
                test.charAt(1) == &#39;1&#39; ? null : 1,
                test.charAt(2) == &#39;1&#39; ? null : "OK",
                test.charAt(3) == &#39;1&#39; ? null : "OK"))
                .orElse(Collections.emptyList()).size();
    }

  • Nous mettons à jour respectivement le nom, l'âge et le pseudo en fonction des besoins de l'entreprise : pour le nom, nous pensons que le client passe null afin de remettre le nom à vide. Pour permettre une telle opération, utilisez l'Optionnel. orElse, première méthode Convertissez simplement la clé en une chaîne vide.
  • Pour l'âge, nous pensons que si le client souhaite mettre à jour l'âge, il doit dépasser un âge valide. Il n'y a pas d'opération de réinitialisation pour l'âge. Vous pouvez utiliser la méthode Facultative orElseThrow pour lancer une IllegalArgumentException lorsque la valeur est vide. .

  • Pour le pseudo, comme le nom dans la base de données ne peut pas être nul, vous pouvez définir en toute sécurité le pseudo sur invité plus le nom retiré de la base de données.

  • @PostMapping("right")
    public UserEntity right(@RequestBody UserDto user) {
        if (user == null || user.getId() == null)
            throw new IllegalArgumentException("用户Id不能为空");
    
        UserEntity userEntity = userEntityRepository.findById(user.getId())
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
    
        if (user.getName() != null) {
            userEntity.setName(user.getName().orElse(""));
        }
        userEntity.setNickname("guest" + userEntity.getName());
        if (user.getAge() != null) {
            userEntity.setAge(user.getAge().orElseThrow(() -> new IllegalArgumentException("年龄不能为空")));
        }
        return userEntityRepository.save(userEntity);
    }

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer