Lo siguiente se muestra a todos por cada malentendido.
1. Uso excesivo de NULL
Evitar el uso excesivo de NULL es la mejor práctica. Por ejemplo, un mejor enfoque es hacer que el método regrese a la matriz o colección vacía en lugar del valor nulo, porque esto puede evitar que el programa arroje NullPointerException. El siguiente fragmento de código obtendrá una colección de otro método:
List <String> AccountIds = Person.GetAccountIds ();
Cuando una cifra no tiene una cuenta, GetAccountIds () devolverá el valor nulo, y el programa lanzará la excepción de NullPointerException. Por lo tanto, es necesario unirse a la verificación de aire para resolver este problema. Si reemplaza el valor nulo devuelto con una lista vacía, entonces no aparecerá nullpointerException. Además, debido a que ya no necesitamos ver una breve verificación de la variable AccountID, el código se volverá más conciso.
Cuando desea evitar valores nulos, diferentes escenarios pueden tomar diferentes prácticas. Un método es usar el tipo opcional, que puede ser tanto un objeto vacío como un paquete de algunos valores.
Opcional <String> OppectionString = Opcional.ofNullable (NulledString);
De hecho, Java8 proporciona una forma más concisa:
Opcional <String> OppectionString = Oppectional.ofnullable (NullialString);
Java ha admitido el tipo opcional de la versión Java8, pero ha sido ampliamente conocido en el mundo de la programación funcional. Antes de eso, se usó en la versión temprana de Java en Google Guava.
2. Ignorar las anormalidades
A menudo ignoramos las anormalidades. Sin embargo, la mejor práctica es tratar con ellos para principiantes y programadores de Java experimentados. El lanzamiento anormal suele tener un propósito, por lo que en la mayoría de los casos, es necesario registrar eventos que causan anormalidades. No subestimes este asunto. Al menos, para que otros desarrolladores sepan la causa y el efecto, debe explicar por qué no se han tratado estas anormalidades.
Selfie = persona.shootaselfie ();
Una manera simple de enfatizar cierta sin importancia es usar esta información como un nombre de variable anormal, como este:
Copiar código del código de la siguiente manera:
Prueba {Selfie.delete ();} Catch (NullPointterException sin importancia) {}
3. Modificar anormalidades simultáneamente
Esta anormalidad ocurre en el objeto de recopilación, y al mismo tiempo no utiliza el método proporcionado por el objeto Iterator para actualizar el contenido en la colección. Por ejemplo, hay una lista de sombreros aquí, y desea eliminar todos los valores que contienen aletas del oído:
List <ihats = new ArrayList <> (); Hasearflaps ()) {hats.remove (hat);}}
Si este código se ejecuta, concurrentModificationException se lanzará, porque el código lo modificará mientras atraviesa esta colección. Cuando múltiples procesos actúan en la misma lista, cuando uno de los procesos atraviesa la lista, el otro proceso intenta modificar el contenido de la lista, y también pueden ocurrir las mismas anormalidades.
Es muy común en el contenido de recopilación de modificación concurrente multifre -theding, por lo que es necesario usar el método comúnmente utilizado en la programación concurrente, como bloqueos sincrónicos, conjuntos especiales para la modificación concurrente, etc. Java resuelve este problema en un solo hilo y una situación de múltiples hilos.
Recoja objetos y elimínelos en otro ciclo
La solución directa es poner sombreros con aletas en una lista, y luego eliminarlo con otro ciclo. Sin embargo, esto requiere un conjunto adicional para almacenar sombreros para eliminar.
List <ihatstoremove = new LinkedList <> ();
Use el método iterator.remove
Este método es más simple y, al mismo tiempo, no necesita crear una colección adicional:
Iterator <ihatitrator = hats.iterator ();
El método de usar listiterator
Cuando se implementa la recopilación de la colección de la interfaz de la lista, el iterador de la lista es una opción muy adecuada. Iterator que implementa la interfaz de Listitoror no solo admite operaciones de eliminación, sino que también admite operaciones ADD y SET. La interfaz Listotrator implementa la interfaz Iterator, por lo que este ejemplo se parece al método eliminar el método del iterador. La única diferencia es el tipo de iterador de HAT y obtenemos el método iterador -utando el método listotrator (). Los siguientes fragmentos muestran cómo usar el listerator.
Ihat Sombero = new Sombero (); ;
Uso de ListIterator, Llamar el método de eliminar y agregar se puede reemplazar para llamar solo un método establecido:
Ihat Sombero = nuevo Sombrero (); ); / Establecer en lugar de eliminar y agregar}}}
Use el método de transmisión en Java 8
En Java8, los desarrolladores pueden convertir una colección en transmisión y filtro de filtro de acuerdo con algunas condiciones. Este ejemplo dice cómo los sombreros de filtro de la API de la corriente y evitan la concepción de modificación concurrente. sombreros = hats.stream ().
Copiar código del código de la siguiente manera:
.Collect (coleccionista.tocollection (ArrayList :: new));
El método Collectors.Tocollection creará una nueva ArrayList, que es responsable de almacenar el valor de sombreros filtrados. Si las condiciones de filtrado se filtran una gran cantidad de entradas, aquí se generará una gran lista de matrices. Por lo tanto, debe usarlo con precaución.
Use el método list.removeif en Java 8
Puede usar otro método más conciso y claro en el método Java 8 -Removeif:
Copiar código del código de la siguiente manera:
Hats.removeif (ihat :: hasearflaps);
En la parte inferior, usa iterator.remove para completar esta operación.
Use una colección especial
Si decide usar CopyOnWriteArrayList en lugar de ArrayList al principio, no habrá ningún problema. Debido a que CopyOnWriteArrayList proporciona métodos modificados (como establecer, agregar, eliminar), no cambiará la matriz de colección original, pero crea una nueva versión modificada. Esto permite que el recorrido modifique la versión original, de modo que no se descarte concurrentModificationException. Las desventajas de esta colección también son muy obvias. Se genera una nueva colección para cada modificación.
Hay otros conjuntos adecuados para diferentes escenarios, como CopyOnWriteset y concurrenthashmap.
Con respecto a otro error que puede ocurrir durante las modificaciones concurrentes, crea una transmisión a partir de una colección. El criterio general para la transmisión es evitar modificar la colección Back -end al verificar la transmisión. El siguiente ejemplo mostrará cómo manejar correctamente la transmisión:
Lista <Ihat> Filedhats = hats.stream ().
El método PEEK recolecta todos los elementos y realiza acciones establecidas para cada elemento. Aquí, la acción es intentar eliminar los datos de una lista básica, que obviamente es incorrecta. Para evitar tales operaciones, puede probar algunos métodos explicados anteriormente.
4. Defensa
A veces, para colaborar mejor, el código proporcionado por la biblioteca estándar o un tercero debe cumplir con las dependencias comunes. Por ejemplo, es necesario cumplir con el acuerdo conjunto entre hashcode y igual para garantizar que una serie de clases de recolección en el marco de recolección de Java y otras clases que usan el hashcode y los métodos iguales pueden funcionar normalmente. No cumpla con errores como excepción o destrucción de la compilación de código;
El código de error puede colarse en el entorno de producción, causando muchos efectos adversos. Esto incluye una experiencia de interfaz de usuario deficiente, informes de datos incorrectos, un bajo rendimiento de la aplicación, pérdida de datos o más. Afortunadamente, estos errores catastróficos no suelen ocurrir. El hashcode y los iguales se han mencionado anteriormente que la escena que parece puede ser: la colección depende del objetivo para comparar los objetos o comparaciones, al igual que hashmap y hashset. En términos simples, hay dos criterios para este acuerdo:
Si los dos objetos son iguales, entonces el código hash debe ser igual.
Si los dos objetos tienen el mismo código hash, pueden ser iguales o diferentes.
El primer criterio para la destrucción, cuando intenta recuperar datos de un hashmap, causará errores. El segundo criterio significa que los objetos con el mismo código hash no son necesariamente iguales.
Echemos un vistazo a las consecuencias de destruir el primer criterio:
Public static Class Boat {Nombre de cadena privada; GetClass ()! int hashcode () {return (int) (math.random () * 5000);}}
Como puede ver, la clase de botes reescribe los métodos iguales y de hashcode. Sin embargo, destruyó el acuerdo porque hashcode devolvió el valor aleatorio para el mismo objeto para cada llamada. Es probable que el siguiente código no encuentre un barco llamado Enterprise en Hashset, aunque de hecho hemos agregado este tipo de barco por adelantado:
Public static void main (string [] args) {set <Ant> barcos = new Hashset <> (); (Nuevo barco ("Enterprise"));};}
Otro acuerdo es el método final. Aquí hay una referencia al documento oficial de Java sobre su descripción funcional:
El acuerdo convencional de Finalize es: cuando la máquina virtual Javatm determina que cualquier hilo ya no puede acceder al objeto especificado de ninguna manera, se llamará a este método. El método Finalize tiene múltiples funciones, incluido el uso de este objeto para estar disponible para otros hilos nuevamente; Por ejemplo, el método finalizar que indica el objeto de conexión de entrada/salida puede ejecutar la transacción de E/S explícita para interrumpir la conexión antes del objeto descartado permanente.
Puede decidir utilizar el método finalizar en un procesador de archivos para liberar recursos, pero este uso es malo. Debido a que se llama durante el reciclaje de basura y el tiempo de GC no está seguro, no se garantizará el tiempo para finalizar.
5. Use el tipo original en lugar de la parametrización
De acuerdo con la descripción del documento Java: el tipo original no es parameterizado o un miembro no estático de RM (también no herenancia de la interfaz principal o principal). Antes de introducir el tipo genérico Java, no había un tipo alternativo primitivo. Java ha admitido la programación genérica de la versión 1.5, y no hay duda de que esta es una mejora importante de la función. Sin embargo, debido a la compatibilidad hacia atrás, hay una trampa aquí que puede destruir todo el sistema de tipos. Esforzarse el ejemplo:
Listofnumbers = new ArrayList ();
Esta es una lista de números que se define como la ArrayList original. Como no especifica los parámetros de tipo, puede agregarle ningún objeto. Sin embargo, la última línea mapea los elementos que contiene para el tipo int y multiplicado por 2, imprimió los datos después del doble de los datos a la salida estándar.
Este código no cometerá un error durante la compilación, pero una vez que se ejecute, arrojará un error cuando se ejecute, porque está tratando de asignar el tipo de caracteres a la cirugía plástica. Obviamente, si la información necesaria está oculta, el sistema de tipos no ayudará a escribir un código de seguridad.
Para resolver este problema, debe especificar el tipo específico para los objetos en la colección:
List <integer> listofnumbers = new ArrayList <() ();
La única diferencia con el código anterior es la línea que define la colección:
Copiar código del código de la siguiente manera:
Lista <integer> listOfNumbers = new ArrayList <();
La compilación de código modificado no se puede aprobar porque está tratando de agregar una cadena a la colección de solo plástico de almacenamiento esperado. El compilador mostrará un mensaje de error y apuntará a la línea que agrega veinte caracteres a la lista. El tipo genérico de parametrización es una buena idea. En este caso, el compilador puede verificar los tipos posibles, de modo que la posibilidad anormal de tiempo de ejecución debido a las inconsistencias se reducirá considerablemente.
El resumen principal de los cinco programadores de Java anteriores a menudo comete errores, espero que a todos les pueda gustar.