Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 429

Java Nivel Intermedio

CFE

Edición 2023
Propiedad intelectual
Material didáctico preparado por la empresa Global K, S.A. de
C.V., Registrado en Derechos de Autor.

Todos los contenidos de este Sitio (Incluyendo, pero no limitado a,


texto, logotipos, contenido, fotografías, audio, botones, nombres
comerciales y video) están sujetos a derechos de propiedad por las
leyes de Derechos de Autor de la empresa Global K, S.A. de C.V.

Queda prohibido copiar, reproducir, distribuir, publicar, transmitir,


difundir, o en cualquier modo explotar cualquier parte de este este
documento sin la autorización previa por escrito de Global K, S.A.
de C.V. o de los titulares correspondientes.
DESCRIPCION DEL CURSO
En este curso te presentaremos temas intermedios y avanzados del lenguaje
de programación Java, así como buenas prácticas y la aplicación de las
principales APIs de las versiones más recientes del lenguaje, también se verá
la interacción de Java con bases de datos relacionales y otros temas
adicionales que incluyen Maven y la depuración de aplicaciones con
Netbeans.
OBJETIVO DEL CURSO
Al completar el curso podrás:

• Implementar los conceptos de la Programación Orientada a Objetos.


• Comprender y utilizar las Interfaces funcionales y genéricos.
• Implementar expresiones Lambda usando las interfaces funcionales de java.util.function.
• Utilizar la API de Stream en conjunto con expresiones Lambda.
• Manejar archivos utilizando los paquetes de IO y NIO.2.
• Aprender a usar fechas utilizando la API de java.time.
• Saber implementar hilos usando las clases Thread y ExecutorService.
• Aprender el manejo básico de MySQL y comandos SQL.
• Conectar tus aplicaciones con una base de datos usando JDBC.
• Comprender el uso de Módulos en Java.
• Conocer qué es Localización.
• Aprender buenas prácticas de seguridad con Java.
• Saber qué es Maven y su uso.
• Depurar y perfilar programas Java usando Netbeans.
ALCANCE
• El curso está diseñado para que los participantes conozcan a un nivel
intermedio y avanzado las APIS principales de Java. Durante las clases se
darán ejemplos y se harán ejercicios prácticos con la herramienta de
desarrollo Netbeans.
PRERREQUISITOS
• Experiencia en el lenguaje Java a un nivel básico.
• Comprensión de los conceptos de la programación orientada a objetos.
• Deseable tener conocimientos en algún lenguaje orientado a objetos como
Python, C#, Kotlin.
• Conocimientos básicos de SQL.
• Deseable conocimiento básico del uso de herramientas como Netbeans.
AUDIENCIA
• Este curso está dirigido a aquellos programadores que les interesa conocer
o ampliar sus conocimientos en las APIs principales de Java.
• También está diseñado para aquellos que les interesa la certificación de
Java 11 Developer Certification Exam.
Temario
Capítulo 1: Programación Orientada a Capítulo 10: Manejo de Fechas.
Objetos. Capítulo 11: Manejo de Hilos.
Capítulo 2: Interfaces. Capítulo 12: ParallelStreams
Capítulo 3: Manejo de Generics en Java. Capítulo 13: JDBC – Conectividad de Base
Capítulo 4: Clases anidadas. de Datos Java.
Capítulo 5: Expresiones Lambda. Capítulo 14: Uso de módulos en Java.
Capítulo 6: Interfaces Funcionales. Capitulo 15: Localización.
Capítulo 7: Streams. Capitulo 16: Codificación Segura en Java.
Capítulo 8: Entrada y Salida de Datos en Capítulo 17. Maven.
Java. Capitulo 18. Optimización y Depuración en
Capitulo 9. Manejo de Archivos. Java.
Presentación del grupo

¿Cuál es tu nombre?

¿Cuánto tiempo llevas trabajando con el


lenguaje Java?

¿Con qué versiones de Java has programado?

¿Qué herramientas usas durante el desarrollo


de las aplicaciones en Java?

¿Cuáles son tus expectativas respecto al curso?


Capítulo 1.
Programación Orientada a
Objetos
Objetivos
 Comprender las partes principales de la arquitectura del lenguaje Java.
 Aprender a instalar el JDK y el IDE de desarrollo Netbeans.
 Saber aplicar las abstracciones en Java.
 Aprender a implementar la encapsulación, la herencia y el
polimorfismo en Java.
Arquitectura de Java
Instalación de JDK y el IDE de desarrollo Netbeans
 Enlace de descarga para el Java Development Kit (JDK):
https://www.oracle.com/java/technologies/java-se-glance.html

 Para descargarlo deberás iniciar sesión con tu


cuenta de Oracle, si no tienes una cuenta
puedes darte de alta fácilmente proporcionando
algunos datos básicos.
Validación de la instalación de Java
Abrir una ventana de Windows o de Shell y dar los siguientes comandos.
Instalación del IDE Netbeans
 Descargar la última versión de Netbeans, ejecutar el instalador o
descomprimirlo en un directorio y crear un acceso al ejecutable.
https://netbeans.apache.org/download/index.html
Programación Orientada a Objetos
 La programación orientada a objetos (OOP) es un paradigma de
programación fundamental utilizado por casi todos los desarrolladores
en algún momento de su carrera.

 Los conceptos de la programación orientada a objetos son:


 Abstracción
 Encapsulación
 Herencia
 Polimorfismo
Abstracción de clases
La abstracción se puede definir como “La representación de un objeto
del mundo real de forma simplificada ya sea en un diagrama o en código
de un lenguaje de programación”.

1. Nombre de la clase.

2. Atributos o campos.

3. Métodos.
Instancias de una clase
Ejemplo de la definición de una clase en Java
Creación de instancias u objetos en Java
Representación de objetos en memoria
Paquetes en Java
Importación de una clase en Java
Importación de varias clases
Encapsulación
Modificadores de acceso
Clase encapsulada en Java
Herencia
 La herencia es el concepto de “reúso de código”, es el proceso en el
que una clase adquiere las propiedades (atributos y métodos) de otra.
Herencia en Java
Herencia en Java (Cont.)
Polimorfismo
 Los conceptos de polimorfismo y herencia están íntimamente
relacionados.
 La herencia te permite reusar los atributos y métodos de otra clase.
 El polimorfismo te permite utilizar esos métodos heredados para
realizar diferentes tareas.
 De ahí viene “polimorfismo”, poder realizar un método de diferentes
formas.
 Existen dos tipos de polimorfismo:
•Estático
•Dinámico
Polimorfismo estático
 En Java, y en otros lenguajes de programación orientados a objetos, te
permiten implementar múltiples métodos dentro de la misma clase con
el mismo nombre, pero con diferentes parámetros, a esto se le conoce
como sobrecarga de métodos y representa una forma estática de
polimorfismo.
Polimorfismo dinámico
 Esta forma de polimorfismo nos permite que el compilador determine
el método que se va a ejecutar de acuerdo al objeto creado en la
variable. La Java Virtual Machine necesita realizar esa determinación
en tiempo de ejecución.
Clases Abstractas
 Son aquellas que sirven de
base para la definición de las
subclases.
 No se pueden instanciar
debido a que no están
completamente definidas o no
tienen significado práctico
para la aplicación.
 Se marcan con la palabra
reservada “abstract”.
 Pueden tener métodos
concretos y/o abstractos.
Clases abstractas en Java
Clase hija de una clase abstracta
Interfaces en Java
 Definen un comportamiento que una o más clases esperan
implementar.

 Una clase describe los atributos y comportamientos de un objeto, una


interfaz solo define los métodos que usará e implementará una clase.
Interfaces en un diagrama
Interfaz en Java
Implementando una interfaz en Java
Resumen del capítulo

La Programación Orientada a Objetos en Java es


un enfoque de programación que se basa en la
creación y manipulación de objetos para modelar
sistemas y aplicaciones, esto permite la
modularidad, la reutilización de código y un diseño
más organizado y mantenible.
Evaluación Práctica
Durante el curso estarás implementando una aplicación de consola de banca electrónica.

Conforme avancemos en los temas se irán agregando funcionalidades a la práctica.

Visión del Proyecto: Banca Electrónica.

Tu compañía está planeando cambiarse a la plataforma de Java, y debido a que la empresa


tiene miles de desarrolladores que utilizan diferentes lenguajes, desea realizar un prototipo de
una aplicación que sirva como guía para el resto de los desarrollos y migraciones, para ello se
ha elegido el realizar una aplicación simplificada de “BANCA ELECTRONICA”.

Se desea realizar una aplicación bancaria que permita el acceso a sus servicios de forma
online y en horario 7 x 24 que acerque la sucursal bancaria a los clientes ofreciendo todo tipo
de servicios, en la primera versión se iniciará una aplicación standalone con los servicios
básicos, como son el manejo clientes y la operación de los diversos tipos de cuentas.
Proyecto de Banca Electrónica
El diagrama inicial propuesto es el siguiente:
Evaluación Práctica 1
Práctica 1.1 Crear un proyecto en Netbeans que se llame BancaElectronica, crear tres
paquetes que se llamen presentación, modelo e integración. En el paquete modelo
implementar cada una de las clases del diagrama del proyecto.

Práctica 1.2 En la clase principal del proyecto, en la clase que tiene el método main, crear un
objeto de tipo Banco, dos clientes con sus respectivos datos y agregarle a cada uno de ellos
dos cuentas, una de Ahorros y otra de Cheques.

Practica 1.3 Ejecutar el proyecto y verificar que todo funcione correctamente.


¿Qué es una clase en Java?
https://docs.oracle.com/javase/tutorial/java/concepts
/class.html
Programación Orientada a Objetos.
https://docs.oracle.com/javase/tutorial/java/concepts
/index.html
Herencia.
https://docs.oracle.com/javase/tutorial/java/concepts
/inheritance.html
Paquetes.
Referencias https://docs.oracle.com/javase/tutorial/java/concepts
Bibliográficas /package.html
Capítulo 2.Interfaces
Objetivo
En este capítulo aprenderás:

• El uso de las interfaces a partir de Java 8.

• El uso de las interfaces a partir de Java 9.

• La definición, estructura y uso de las interfaces funcionales.


Interfaces en Java 8
Java 8 te permite implementar
dos métodos especiales dentro
de una interfaz:
 Métodos estáticos, son
códigos independientes y
pueden ser llamados usando
el nombre de la interface.
 Métodos default, son
aquellos que heredan código
a las subinterfaces o clases
que implementan la interface.
Interfaces a partir de Java 9

 En La versión de Java 9 se agregaron los métodos privados.

 Estos métodos son útiles cuando existe duplicidad de lógica en los


métodos default.
Duplicidad de lógica
Métodos privados evitando lógica duplicada
Interfaces Funcionales
 Son aquellas que contiene un solo método público y abstracto,
adicionalmente también te permiten tener métodos estáticos, default y
privados.
@FunctionalInterface
 Se marca la interfaz con la anotación @FunctionalInterface para
validar que se cumplan las reglas de implementación.
Resumen del capítulo
Las interfaces en Java son una herramienta fundamental para la
programación orientada a objetos, que permite definir contratos de
comportamiento y facilita la creación de clases que cumplen con esos
contratos, lo que mejora la modularidad y la flexibilidad del código.
Evaluación Práctica 2
Hasta este momento tenemos en funcionamiento nuestras entidades, pero nos faltan las
operaciones para realizar los movimientos, para lograr esta funcionalidad utilizaremos el
concepto de interfaces, en donde separaremos la funcionalidad para facilitar las operaciones
de los clientes y las cuentas.

Si notamos, a nuestra aplicación ahora le estamos agregando dos interfaces que representan
a los servicios: ServicioCuentas y ServicioClientes.

Los requerimientos para la práctica son los siguientes:

Práctica 2.1 Implementar las interfaces en sus respectivas clases, en Banco ServicioClientes y
en Cliente ServicioCuentas, implementar la funcionalidad de cada uno de los métodos.

Práctica 2.2 Validar el funcionamiento de las clases y sus métodos desde la clase principal,
invocando sobre los objetos, previamente creados, los métodos de servicio de las interfaces
implementadas.
Evaluación práctica
Interfaces
https://docs.oracle.com/javase/tutorial/java/concepts
/interface.html
Modificadores en una interfaz
https://docs.oracle.com/javase/specs/jls/se16/html/jl
s-9.html#jls-9.1.1
Métodos en una interfaz
https://docs.oracle.com/javase/specs/jls/se16/html/jl
s-9.html#]ls-9.4
Sobreescritura
https://docs.oracle.com/javase/specs/jls/se16/html/jl
Referencias s-9.html#]ls-9.4.2
Interfaces funcionales
Bibliográficas https://docs.oracle.com/javase/specs/jls/se16/html/jl
s-9.html#ls-9.8
Capítulo 3. Manejo de
Generics en Java
Objetivo
Dentro de este capítulo aprenderás a:

 Implementar métodos y clases genéricas.

 Usar los genéricos dentro de colecciones.

 Utilizar las diferentes colecciones que existen en la API de colecciones


de Java.
Genéricos
 Los genéricos significan tipos parametrizados.
 La idea es permitir que el usuario decida en tiempo de uso el tipo de
dato que desea utilizar, ya sea Integer, String, etc, o tipos definidos
por el usuario en los parámetros de los métodos, las clases e
interfaces.
 Usando genéricos es posible crear clases que funcionen con
diferentes tipos de datos.
Clase genérica en Java
Uso de genéricos en Java
Clase genérica con múltiples tipos
Uso de clase con múltiples genéricos
Funciones genéricas
Usando funciones genéricas
Colecciones en Java y genéricos
 Algo interesante de las colecciones en Java, es que ya tienen
implementados los genéricos, esto permite que tengas una seguridad
de tipos y puedas acotar los objetos que vas a usar en tus colecciones.
API de colecciones (java.util)
List
Esta es la interfaz de las colecciones más utilizadas en Java, las
características que tiene son:

 Los elementos están ordenados por posición en la lista.

 Las búsquedas son iterando la lista o usando el índice.

 Objetos duplicados son permitidos.


List en Java
Set
 La interfaz Set se encuentra dentro del paquete de colecciones
(java.util), y extiende de la interfaz Collection.

 Es una colección no ordenada de objetos (aunque hay una


implementación que si los ordena).

 Esta colección tiene las siguientes características:


1. Los elementos no pueden buscarse por índice.

2. Elementos duplicados no son permitidos.


Set en Java
Queue
La interfaz Queue (cola) está presente en el paquete java.util y extiende
de la interfaz Collection, se utiliza para contener los elementos que se
van a procesar en orden FIFO (primero en entrar, primero en salir).
Esta colección tiene las siguientes características:
 Implementa la política FIFO (First-in, first-out).
Queue en Java
Mapas en Java
Map
La interfaz Map se encuentra al igual que las anteriores en el paquete de
java.util, representa una estructura de datos que almacena los valores
llave-valor. No es un subtipo de la interfaz Collection.
Algunas de las características de la interfaz Map son:
 Un Map no puede contener llaves duplicadas y cada llave sólo se le
puede asignar un valor.
 Algunas implementaciones permiten una clave y un valor nulos como
HashMap y LinkedHashMap, pero otras no lo permiten como TreeMap.
 El orden de un mapa depende de las implementaciones específicas,
por ejemplo, TreeMap y LinkedHashMap tienen un orden predecible,
mientras que HashMap no.
Map en Java
Ordenando colecciones (Interfaz Comparable)
Ordenando colecciones (Interfaz Comparator)
Usando y aplicando Comparator
Resumen del capítulo
Las colecciones en Java son estructuras de datos que permiten almacenar y
manipular una serie de elementos, mientras que los genéricos son una
característica que agrega seguridad de tipos y reutilización de código al
permitir trabajar con tipos de datos genéricos y parametrizados. Ambos
conceptos son fundamentales para escribir código más robusto y eficiente en
Java.
Evaluación Práctica 3
En esta práctica realizaremos algunos cambios en nuestro proyecto, le agregaremos la
funcionalidad de ordenamiento a nuestros objetos.

Los requerimientos para la práctica son los siguientes:

3.1.- Implementar la interfaz Comparable en las clases Cliente y Cuenta.

• En la clase Cliente implementar el ordenamiento por número.

• En la clase Cuenta implementar el ordenamiento por saldo.

3.2.- Cambiar los arreglos por colecciones para facilitar el procesamiento de los datos. Es
importante usar las colecciones que se muestran en el diagrama.

3.3.- Realizar los cambios pertinentes a los métodos para que funcionen con las colecciones.

3.4.- Validar que los métodos funcionen correctamente en la clase principal.


Evaluación práctica
Generics
https://docs.oracle.com/javase/specs/jls/se16/html/jl
s-8.html#jls-8.1.2
Collections
https://docs.oracle.com/javase/tutorial/collections/int
ro/index.html
Comparable
https://docs.oracle.com/en/java/javase/16/docs/api/j
ava.base/java/lang/Comparable.html
Comparator
Referencias https://docs.oracle.com/en/java/javase/16/docs/api/j
ava.base/java/util/Comparator.html
Bibliográficas
Capítulo 4. Clases Anidadas
Objetivo
En este capítulo aprenderás a:

 Implementar una clase anidada miembro.

 Implementar una clase anidada estática.

 Implementar una clase anidada anónima.


Clase anidada Miembro
 El lenguaje de programación de Java te permite definir una clase
dentro de otra clase.

 A este tipo de estructura se le conoce como clase anidada.


Instancia de una clase anidada miembro
Clase Anidada Estática
 Al igual que con los métodos y las variables de clase, una clase
anidada estática se asocia con su clase externa, y al igual que los
métodos de clase estática, una clase anidada estática no puede
referirse directamente a variables de instancia o métodos definidos en
su clase adjunta, sólo puede usarlos a través de una referencia de
objeto.
Instancia de clase Anidada Estática
Clase Anidada Anónima
 Es una clase anidada sin nombre, en la que se crea un único objeto.

 Una clase anidada anónima puede ser útil cuando se crea una
instancia de un objeto con ciertos "extras" como los métodos de
sobrecarga de una clase o interfaz, sin tener que implementarla o
extenderla explícitamente de una clase.
Uso de clase Anidada anónima
Usos de las clases Anidadas
 Es una forma de agrupar lógicamente las clases que solo se usan en
un lugar.

 Aumenta la encapsulación.

 Puede conducir a un código más legible y fácil de mantener.


Resumen del capítulo
Las clases anidadas en Java permiten una organización y encapsulación más
efectiva del código, así como la implementación de patrones de diseño como
el patrón de fábrica o el patrón de estrategia de manera más concisa.
Además, las clases anidadas pueden ayudar a mejorar la legibilidad del
código al agrupar clases relacionadas en el contexto adecuado.
Evaluación Práctica 4
En esta práctica mejorarás el funcionamiento de tu aplicación. Para repasar el uso de las clases anidadas,
puedes implementar el patrón de diseño Builder (usando clases anidadas) para crear los Clientes.

El patrón de diseño Builder permite crear objetos que habitualmente son complejos utilizando otro objeto
más simple que los construye paso por paso.

Este patrón Builder se utiliza en situaciones en las que debe construirse un objeto repetidas veces o
cuando este objeto tiene gran cantidad de atributos y objetos asociados, y en donde usar constructores
para crear el objeto no es una solución cómoda.

4.1 Implementa el patrón de diseño Builder para la clase Cliente. Investiga en internet en qué consiste
este patrón, en qué mejora el código y cómo se implementa, si tienes dudas consulta con tu instructor
cómo se aplica en la programación este patrón.

4.2 Implementa el patrón de diseño Singleton para la clase Banco. Investiga en internet en que consiste
este patrón, en qué mejora el código y cómo se implementa, si tienes dudas consulta con tu instructor
cómo se aplica en la programación este patrón.
Clases anidadas
https://docs.oracle.com/javase/specs/jls/se16/html/jl
s-8.html#d5e12711
https://docs.oracle.com/javase/tutorial/java/javaOO/
nested.html
Clases internas
https://docs.oracle.com/javase/specs/jls/se16/html/jl
s-8.html#d5e12759
Clases anónimas
Referencias https://docs.oracle.com/javase/tutorial/java/javaOO/
anonymousclasses.html
Bibliográficas
Capitulo 5. Expresiones
Lambda
Objetivo
En este capítulo aprenderás a:
 Implementar clases anidadas anónimas con interfaces.

 Implementar clases anidadas con interfaces funcionales.

 Aprender qué es una expresión Lambda y su uso.

 Crear Lambdas con genéricos.


Interfaces y clases Anónimas
 En el capítulo anterior aprendiste cómo crear clases anidadas en sus
diferentes modalidades.
 ¿Cuál es la relación de las clases anidadas y las interfaces?
 Las clases anidadas Anónimas son las más utilizadas en conjunto con
las interfaces.
Clase anidada Anónima desde interfaz
Interfaz funcional y clases Anónimas
Las interfaces funcionales son interfaces que contienen un solo método
abstracto y una de las características principales de estas interfaces es
que pueden implementarse de cualquier forma, porque se adaptan a
cualquier necesidad.
Clase Anónima desde interfaz funcional
Expresiones Lambda y su uso
 En el tema anterior aprendiste cómo usar una interfaz funcional con
una clase anidada anónima, aunque es una funcionalidad que
simplifica mucho el uso de las interfaces, a partir de Java 8 esto se
puede simplificar aún más usando expresiones Lambda.
 Para comprender de donde salen las expresiones Lambda revisemos
la misma interfaz que usamos en el tema anterior.
Netbeans y la clase Anónima
Expresión Lambda
Partes de Lambda
Interfaz funcional y Lambda
Creando expresiones Lambda con Generics
Usando expresiones Lambda con Generics
Resumen del capítulo
Las Lambdas en Java se utilizan principalmente para mejorar la legibilidad y
la concisión del código en situaciones donde se necesita implementar
interfaces funcionales. Esto es especialmente útil en programación orientada
a eventos, manejo de colecciones, proceso de streams y otras situaciones en
las que se requiere un comportamiento específico de manera rápida y
sencilla.
Evaluación Práctica 5
Tienes una clase llamada Persona con los atributos: int clave, String nombre, int edad y una
interface nombrada ManejaPersona que tiene las operaciones para realizar altas, bajas,
cambios y consultas de los objetos tipo Persona en una tabla de una base de datos.

La interfaz está definida así:

public interface ManejaPersona {

public boolean agregar(Persona p);


public boolean eliminar(int clave);
public boolean actualizar(Persona p);
public boolean consultar(int clave);

}
Evaluación práctica
5.1 Los requerimientos para esta práctica son los siguientes:

• Definir una interfaz funcional que sustituya a la interfaz ManejaPersona.


• Definir cuatro expresiones Lambda que realicen las operaciones mencionadas.
• Crear un proyecto en Java que implemente estos requerimientos, no es necesario tener la
base de datos ni la tabla, en la implementación de cada expresión Lambda imprimir solo una
sentencia en lenguaje SQL que podría realizar cada operación en la base de datos.
Expresiones Lambda
https://docs.oracle.com/javase/tutorial/java/javaOO/l
ambdaexpressions.html
Clases anónimas y expresiones Lambda
https://docs.oracle.com/javase/tutorial/java/javaOO/
whentouse.html
Sintaxis de Lambda
https://docs.oracle.com/javase/specs/jls/se16/html/jl
Referencias s-15.html#ls-15.27

Bibliográficas
Capítulo 6. Interfaces
Funcionales
Objetivos
Dentro de este capítulo aprenderás a:
 Implementar las interfaces funcionales del paquete java.util.function.

 Implementar interfaces binarias.

 Implementar interfaces primitivas.


Interfaz funcional Predicate
La interfaz funcional Predicate se encuentra en el paquete
java.util.function, esta mejora la capacidad de administración del código y
tiene como objetivo realizar pruebas dentro del código.
Lambda de Predicate
Interfaz funcional Consumer
 Es una interfaz funcional definida en el paquete java.util.function.
 Contiene un método abstracto accept () que regresa void y un método
default andThen().
 Se puede utilizar como destino de asignación para una expresión
Lambda o de referencia a un método.
Lambda de Consumer
Interfaz funcional Function
 La interfaz Function es parte del paquete java.util.function que se ha
introducido desde Java 8 para implementar la programación funcional
en Java.
 Representa una función que toma un argumento y produce un
resultado.
Lambda de Function
Interfaz funcional Supplier
 La interfaz Supplier es parte del paquete java.util.function que se ha
introducido desde Java 8 para implementar la programación funcional
en Java.
 Representa una función que no toma ningún argumento, pero produce
un valor de tipo T.
Lambda de Supplier
Interfaz funcional UnaryOperator
 La interfaz UnaryOperator<T> es parte del paquete java.util.function
que se ha introducido desde Java 8 para implementar la programación
funcional en Java. Representa una función que toma un argumento y
opera sobre él, sin embargo, lo que la distingue de una función normal,
es que tanto su argumento como su tipo de retorno son iguales.
Lambda de UnaryOperator
Interfaces Binarias
Las interfaces binarias no son más que interfaces funcionales que
reciben dos parámetros de entrada.
Algunas de las interfaces binarias son:
 BinaryOperator<T>: Recibe dos parámetros del mismo tipo de dato y
retorna el mismo tipo de dato ((T,T)->T).
 BiPredicate<T,U>: Recibe dos parámetros de entrada de cualquier
tipo de dato y retorna boolean ((T,U)-> boolean).
 BiFunction<T,U,R>: Recibe dos parámetros de entrada de cualquier
tipo de dato y retorna cualquier tipo de dato ((T,U)->R).
 BiConsumer<T,U>: Recibe dos parámetros de entrada de cualquier
tipo de dato y no retorna nada ((T,U)->void).
Interfaces Binarias en Java
Interfaces Primitivas
Java trae una versión especializada de las interfaces funcionales para
evitar operaciones de autoboxing cuando las entradas o salidas son
primitivas.
Algunas de las interfaces funcionales que funcionan con primitivos son:
 ToIntFunction<T>: Recibe un objeto y retorna un entero: (T->int).

 ToDoubleFunction<T>: Recibe un objeto y retorna un double:


(T->double).
 IntPredicate: Recibe un int y retorna un boolean (int->boolean).

 IntConsumer: Recibe un int y no retorna nada (int->void).


Interfaces primitivas en Java
Resumen del capítulo
Las interfaces funcionales en Java son interfaces que contienen un único
método abstracto y se utilizan para definir contratos claros para
comportamientos específicos. Estas interfaces son fundamentales para la
programación funcional en Java y se utilizan en conjunto con Lambdas para
escribir código más conciso y legible, especialmente en operaciones
relacionadas con colecciones y flujos de datos.
Evaluación Práctica 6
6.1 Crea un proyecto en Netbeans que se llame InterfacesFuncionales, introduce en el
programa “main” cada uno de los ejemplos vistos en este capítulo de las interfaces funcionales
Predicate, Consumer, Supplier, Function, UnaryOperator que usan expresiones Lambdas,
analiza y prueba su funcionalidad.

6.2 Introduce los códigos de los ejemplos de las interfaces binarias y de aquellas que manejan
tipos primitivos, prueba los códigos, analiza cómo funcionan y deduce en dónde podrías
aplicarlas. ¿Podrías dar ejemplos de su uso?.
Interfaces Funcionales
https://docs.oracle.com/javase/specs/jls/se16/html/jl
s-18.html#ls-18.5.3
Paquete java.util.function
https://docs.oracle.com/en/java/javase/16/docs/api/j
ava.base/java/util/function/package-summary.html

Referencias
Bibliográficas
Capítulo 7. Streams
Objetivo
En este capítulo aprenderás a:
 Reconocer los tipos de operaciones de la API de Stream.

 Implementar Operaciones Intermedias.

 Implementar Operaciones Finales.

 Implementar Operaciones Finales en corto circuito.


¿Qué es un Java Stream?
 Un Java Stream es un componente que es capaz de iterar
internamente sus elementos, lo que significa que puede iterar sus
elementos por sí mismo.
 Por el contrario, cuando utilizas las funciones de iteración de las
colecciones de Java, por ejemplo, un iterador de Java o un ciclo para ir
por cada uno de sus elementos, debes implementar y controlar la
iteración de los elementos.
Iterando una colección sin Stream
 Imagina que tienes la siguiente lista:
Iterando colección sin Stream
 Si quieres mostrar a las personas que tienen una edad mayor a 30,
tendrías que hacer lo siguiente:
Iterando colección con Stream
 Si haces lo mismo con la API de Stream te quedaría de la siguiente
forma:
Características de la API de Stream
 Es una secuencia de elementos con múltiples métodos unidos a través
del operador punto.
 Es inmutable.
 Puede usarse sólo una vez.
 Provee de múltiples clases para diferentes tipos de dato.
 Stream<T> para procesar cualquier tipo de objeto.
 DoubleStream, IntStream, LongStream, usados para procesar
primitivos.
Tipos de Operaciones en la API de Stream
 Operaciones Iniciales
stream(), IntStream.range(), parallelStream(), Arrays.stream().

 Operaciones Intermedias
filter(Predicate<T>), map(Function<T,R>), sorted(),
sorted(Comparator<T>), mapToDouble(ToDoubleFunction<T>),
mapToInt(ToIntFunction<T>), peek(Consumer<T>).

 Operaciones Finales
forEach(Consumer<T>), count(), sum(), average(), collect(Collectors).
Tipos de Operaciones en la API de Stream

 Operaciones finales con corto circuito

findFirst(), findAny(), anyMatch(Predicate<T>), allMatch(Predicate<T>),


noneMatch(Predicate<T>), takeWhile(Predicate<T>)
Lista usada para los ejemplos de cada Operación
Operaciones Intermedias (filter())
filter(Predicate<T>): Esta operación intermedia se usa para filtrar los
objetos dentro de un stream.
En su interior esta operación recibe un Predicate, es decir que debes de
agregar una expresión Lambda condicional.
Ejemplo de filter()
 De la lista de personas se necesita mostrar a todas las personas que
su ciudad de Origen sea CDMX y que tengan más de 18 años.
Operaciones Intermedias (map)
 map(Function<T,R>): Esta es una operación intermedia que se usa
para convertir un objeto dentro del Stream en otro tipo.
 Es importante saber que esta operación sí puede afectar a las
operaciones posteriores a él, por ejemplo, si dentro de la operación
map entra una Persona, pero sale un String, para la siguiente
operación después del map, el tipo de entrada ahora es String.
Ejemplo de map()
 Se requiere crear una lista en la cual se almacenarán todos los
nombres de Personas que comiencen con la letra ‘E’.
Operación Intermedia peek()
 peek(Consumer<T>): Esta es una operación que se asemeja mucho
a la operación final forEach(), pero con la diferencia que esta
operación se puede agregar n veces.
 La operación peek() es muy útil cuando se necesita imprimir resultados
intermedios del Stream o para modificar un objeto dentro del Stream
sin comprometer el tipo de dato.
Ejemplo de peek()
 Se necesita agregar en una nueva lista a las personas que son del
EDOMEX, antes de agregar a la lista cada persona se debe de
imprimir.
 Para imprimir resultados intermedios en el stream usaremos peek.
Operación intermedia sorted()
 sorted(): Esta operación intermedia invoca al Comparable<T> que
debe de estar implementada dentro de la clase Persona.
 Es un método que usa la ordenación por defecto (orden natural) que
tienen los objetos dentro del Stream.
Ejemplo de sorted()
 Dentro de la clase Persona se desea implementar el ordenamiento por
defecto por nombre, y mostrar los elementos de la lista ordenados
usando sorted().
 Para realizar este ejercicio, primero debemos implementar
Comparable<T> en Persona.
Operación intermedia sorted(Comparator<T>)
 sorted(Comparator<T>): A diferencia con la operación anterior, este
sorted te permite crear tus propios tipos de ordenación en el Stream,
ya sea usando una expresión Lambda o usando los métodos estáticos
de la interfaz funcional Comparator.
Ejemplo sorted(Comparator<T>)
 Se necesita ordenar a las Personas de la lista por edad.
 Para realizar este ejercicio se debe de implementar un Comparator
dentro del método sorted().
 Algo importante a resaltar, es que cuando agregues un Comparator al
sorted() se ignora el Comparable<T> que viene por defecto en
Persona.
Operaciones finales(forEach())
 forEach(Consumer<T>): Esta operación final es una de las más
utilizadas en un stream, aunque su uso más común es para imprimir
resultados al final del stream, también se puede usar para ejecutar
métodos, agregar a listas, agregar elementos a archivos, etc.
Ejemplo de forEach
 Se desea imprimir en la consola las persona que tengan una edad par.
Operaciones finales (count())
 count(): Esta es una de las operaciones más sencillas de la API de
Stream, esta operación realiza un conteo de objetos que llegan al final
del stream, y cuando se terminen de procesar todos los elementos
retorna un long que representa la cantidad de objetos que llegaron
hasta el final.
Ejemplo de count()
 Se necesita saber cuántas personas no son de la CDMX.
 Para este ejercicio se usará el método estático de
Predicate.not(Predicate<T> pr).
Operaciones finales (sum)
 sum(): Esta operación puede utilizarse para realizar la operación
aritmética de suma.
 A pesar de que es una operación muy sencilla, no la podemos utilizar
a la ligera, es una operación que obligatoriamente debe de recibir
primitivos, para logra esto se pueden usar las operaciones intermedias
de mapToDouble(), mapToInt() o mapToLong().
Ejemplo sum
 Se necesita sumar todas las edades de las Personas.
 Para usar sum() usaremos la operación intermedia mapToInt() porque
las edades son de tipo entero.
Operaciones finales (average())
 average(): Esta es una operación muy similar a sum(), pero se
diferencia en que esta operación calcula el promedio y el retorno de
esta operación es un Optional<T>.
 La clase Optional<T> es una clase que permite tomar decisiones en
función de si el valor existe o no.
 En la operación de average se usa una clase especial de Optional que
se llama OptionalDouble.
Ejemplo average()
 Calcular la edad promedio de las Personas.
 Para este ejercicio usaremos el método intermedio
mapToDouble(ToDoubleFunction<T>).
Operaciones finales(collect())
 collect(Collectors): Esta es una operación final que cambia su
comportamiento de acuerdo con el método que tiene en su interior, por
ejemplo, si tiene el método Collectors.toList() convierte la salida del
stream a una List<T> o si usa el Collectors.toMap() podemos convertir
la salida del stream a un mapa.
Ejemplo collect()
 Se desea generar 3 colecciones:
 En la primera colección se necesita una lista con todas las personas
mayores de edad. (Collectors.toList()).
 En la segunda se necesita un Mapa donde las personas estén
agrupadas por CiudadOrigen.(Collectors.groupingBy()).
 En la última colección se necesita un Mapa donde se separe la
colección en dos, las personas que tengan más de 25 años y las
personas que no. (Collectors.partitioningBy()).
Ejemplo collect() código
Operaciones finales con corto circuito (findFirst())
 findFirst(): Esta es una operación que entrega el primer objeto que
llegue al final del stream.
 Esta operación usa la clase Optional<T> usada para preguntar si un
elemento llega o no al final del stream.
 FindFirst() es muy útil para buscar objetos dentro de un stream y
cuando se usa en paralelo es determinística.
Ejemplo findFirst()
Se necesita buscar una persona que cumpla con los siguientes
requerimientos:
1.- Tenga más de 27 años.
2.- Que sea de CDMX.
3.- Que sea hombre.
Operaciones finales con corto circuito (findAny())
 findAny(): Esta operación que funciona casi igual que la operación
findFirst(), pero tiene la diferencia que puede variar el resultado de la
operación cuando se esté usando un parallelStream (no
determinística).
Ejemplo findAny()
 Se necesita buscar la primera persona que contenga una edad par.
Operaciones finales con corto circuito (anyMatch())
 anyMatch(Predicate<T>): Esta operación regresa true al encontrar el
primer objeto que cumpla con la condición del Predicate<T>.
Ejemplo anyMatch()
 Se necesita saber si alguna persona es de la CDMX.
 Esta operación realiza el corto circuito en cuanto encuentre al primer
objeto que cumpla con el Predicate.
Operaciones finales con corto circuito(allMatch())
 allMatch(Predicate<T>): Esta operación entrega true si todos los
elementos del Stream cumplen con la condición.
 Esta operación realiza corto circuito en cuanto encuentre al primer
objeto que no cumpla con la condición.
Ejemplo de allMatch()
 ¿Todas las personas de la colección son mayores de 18 años?
Operaciones finales con corto circuito(noneMatch())
 noneMatch(Predicate<T>): Esta operación final entrega true si todos
los objetos del stream no cumplen con el Predicate.
 Realiza corto circuito cuando encuentre al primer objeto que cumple
con el Predicate.
Ejemplo de noneMatch()
 ¿Todas las personas no son de ‘SON’?, con noneMatch, en cuanto
encuentre a una persona que sea de ‘SON’ retorna false.
Operaciones finales con corto circuito (takeWhile())
 takeWhile(Predicate<T>): Toma los objetos dentro de un stream
mientras cumplan la condición.
 Esta es una operación se puede usar tanto como intermedia y final con
corto circuito.
Ejemplo takeWhile()
 Obtener las primeras personas que sean de sexo femenino ‘F’ en un
Stream.
Resumen del capítulo
La clase Stream en Java es una herramienta poderosa para realizar
operaciones de procesamiento de datos de manera funcional y eficiente en
secuencias de elementos. Facilita la escritura de código limpio y legible,
permite el uso de paralelismo para mejorar el rendimiento y es esencial en
situaciones donde se necesite manipular y transformar datos de manera
eficaz, como en operaciones de colección y procesamiento de flujos de datos.
Evaluación Práctica 7
Hasta el momento hemos utilizado los ciclos tradicionales para crear los métodos de los
servicios de Cuentas y Clientes.

Los requerimientos para la práctica son los siguientes:

7.1 Adaptar todos los métodos para que funcionen con la API de Stream. (Las funciones del
ServicioClientes y ServicioCuentas).

7.2 Validar que todos los métodos funcionen correctamente, realizando pruebas en la clase
principal.

Nota: Para realizar esta práctica es necesario conocer las operaciones iniciales, intermedias
con corto circuito y finales de la API de Stream.
Stream
https://docs.oracle.com/en/java/javase/16/docs/api/j
ava.base/java/util/stream/Stream.html
Procesamiento de datos con Streams
https://www.oracle.com/technical-
resources/articles/java/ma14-java-se-8-
streams.html
https://docs.oracle.com/javase/tutorial/collections/str
Referencias eams/index.html

Bibliográficas
Capítulo 8. Entrada y Salida
de Datos
Objetivos
En este capítulo aprenderás a:
 Diferenciar entre IO y NIO.2.

 Serializar y deserializar objetos.


IO
 Java IO está orientado al manejo del flujo de datos, esto significa que
lee uno o más bytes a la vez.
 Lo que haga con los bytes leídos depende de ti.
 No se almacenan en caché en ningún lugar.
 No se puede avanzar y luego retroceder en los datos de una
secuencia.
 Si necesitas avanzar y retroceder en los datos leídos de una
secuencia, primero deberás almacenarlos en un búfer.
IO
Ejemplo lectura archivo con IO
NIO
 El enfoque orientado al búfer de Java NIO es ligeramente diferente.
 Los datos se leen en un búfer desde el cual se procesan
posteriormente.
 Puede avanzar y retroceder en el búfer según sea necesario, esto te
da un poco más de flexibilidad durante el procesamiento, sin embargo,
debes verificar si el búfer contiene todos los datos que necesitas para
procesarlos por completo, además debes asegurarte de que, al leer
más datos en el búfer, no sobreescribir los datos del búfer que aún no
se han procesado.
NIO
Ejemplo de NIO
NIO.2
El paquete de NIO.2 es una evolución del paquete de NIO, ya que te
provee de las siguientes funcionalidades:
 Navegación sencilla en directorios.

 Soporte para reconocer enlaces simbólicos.

 Leer atributos como permisos.

 Soporte para entrada y salida asíncrona.

 Operaciones básicas sobre archivos.


Serialización de Objetos
 El concepto de Serialización o Persistencia de objetos es el proceso
donde salvas los datos en algún almacenamiento no volátil (disco
duro, base de datos, archivos, etc.).
 Cuando se dice que serializamos un objeto realmente almacenas los
atributos de un objeto (estructura y contenido) en un archivo ya sea en
nuestra computadora local o en algún servidor remoto.
 Para serializar un objeto, la clase debe de implementar la interfaz
java.io.Serializable.
Ejemplo de Serialización
Código para Serializar un Objeto
Deserialización de Objetos
 A este proceso también se le conoce cómo no-persistencia y es el
proceso en el cual llevas un objeto de una memoria no volátil a una
memoria volátil.
 En el caso de Java es cuando pasamos el objeto que se encuentra en
un archivo a la memoria de la máquina virtual de Java.
Código de Deserialización de un Objeto
Resumen del capítulo
El paquete java.io es la API tradicional de Entrada/Salida en Java, mientras
que java.nio introduce una API más moderna y eficiente para manejar
operaciones de E/S, especialmente en situaciones de alto rendimiento. La
elección entre uno u otro depende de las necesidades específicas de tu
aplicación y de si deseas aprovechar las ventajas de E/S no bloquear antes y
otras características avanzadas.
Evaluación Práctica 8
Se desea almacenar un objeto Cliente en un archivo para preservar los datos como medida de
protección, en base a lo aprendido y usando el concepto de serialización/deserialización de
objetos realiza las siguientes prácticas:

8.1 Crea un programa en Java que tenga una clase que permita serializar un objeto de la clase
Cliente usando uno de sus métodos y utilizando otro método para recobrar el objeto
serializado.
8.2 En el método main serialize y deserialize un objeto Cliente, comprueba que funcione de
manera correcta.
IO y NIO
https://docs.oracle.com/javase/8/docs/technotes/gui
des/io/index.html
File IO
https://docs.oracle.com/javase/tutorial/essential/io/fil
eio.html

Referencias
Bibliográficas
Capítulo 9. Manejo de
Archivos
Objetivos
En este capítulo aprenderás a:
 Utilizar la interfaz Path y la clase Paths.

 Manejar archivos utilizando Java.

 Escribir y leer archivos usando la API de Stream.

 Obtener rutas de carpetas y subcarpetas usando list() y walk().


Interfaz Path y la clase Paths
 La interfaz Path de Java es parte de la actualización de Java NIO.2
que Java NIO salió en Java 6 y Java 7.
 La interfaz Path de Java se agregó a Java NIO en Java 7, la interfaz
Path se encuentra en el paquete de java.nio.file, por lo que el nombre
completo de Java para la interfaz Path es java.nio.file.Path.
 Una instancia de Path representa una ruta en el sistema de archivos.
Una ruta puede apuntar a un archivo o directorio y puede ser absoluta
o relativa.
Ejemplo de Path y Paths
Operaciones con archivos
 Realizar operaciones con archivos es algo fundamental en cualquier
lenguaje de programación.
 A continuación, observaremos algunas operaciones que se pueden
realizar con archivos y directorios en Java usando NIO.2.
 La clase java.nio.file.Files en Java proporciona métodos estáticos para
realizar diversas operaciones en archivos y directorios, este paquete
sirve para trabajar con el sistema de archivos de manera más
avanzada y eficiente.
Métodos de la clase java.nio.file.Files
 createFile(Path path, FileAttribute<?>... attrs): Crea un nuevo archivo en la ruta especificada.
 createDirectory(Path dir, FileAttribute<?>... attrs): Crea un nuevo directorio en la ruta
especificada.
 delete(Path path): Borra un archivo o directorio.

 deleteIfExists(Path path): Borra un archivo o directorio si existe.

Copia, Movimiento y Renombrado de Archivos y Directorios:


 copy(Path source, Path target, CopyOption... options): Copia un archivo o directorio.

 move(Path source, Path target, CopyOption... options): Mueve o renombra un archivo o


directorio.
Verificación y Modificación de Propiedades de Archivos:
 exists(Path path, LinkOption... options): Comprueba si un archivo o directorio existe.

 isDirectory(Path path, LinkOption... options): Comprueba si una ruta es un directorio.

 isRegularFile(Path path, LinkOption... options): Comprueba si una ruta es un archivo regular.


Comprobar la existencia de un archivo
Crear un archivo
Crear directorios
Copiar archivos
Mover archivos
Eliminar archivos
Escritura y lectura de archivos con la API de Stream
 La lectura y escritura de archivos es una actividad muy común en
múltiples lenguajes de programación, aunque en Java desde la versión
8 ha cambiado mucho y conforme han avanzado las versiones de
Java, cada vez se le agregan más funcionalidades.
Escritura de un archivo
Lectura de un archivo
Método list()

 Este método funciona como el comando ls (en linux) o el comando dir


(en Windows) en donde sólo nos entrega el contenido de una carpeta.
 Este método retorna un Stream<Path>.
Ejemplo de list()
Método walk()

 Este método es muy similar al método list, pero tiene la diferencia que
este método entra a carpetas y subcarpetas de un directorio.
 Cabe resaltar que este método es más pesado que list, es
recomendable tomar precauciones al utilizarlo.
Ejemplo de walk
Resumen del capítulo
En Java, puedes manejar archivos utilizando las clases y métodos
proporcionados por los paquetes java.io y java.nio.file. Esto te permite
realizar operaciones de lectura, escritura y manipulación de archivos y
directorios en el sistema de archivos de manera efectiva y segura. Además,
ten en cuenta el manejo adecuado de excepciones y el cierre de recursos
para escribir un código robusto y confiable.
Evaluación Práctica 9
Hasta el momento los datos para probar la aplicación los hemos escrito manualmente en la
clase Principal, ahora usaremos algunos archivos para poder probar la funcionalidad de
nuestras clases y validar que toda la aplicación funcione correctamente.

Para esta práctica usaremos el siguiente archivo de datos.


Evaluación Práctica
Donde cada columna representa la siguiente información:
Evaluación Práctica
9.1. Crea el archivo de datos con un editor de textos simple como notepad o vim, en el
directorio de proyectos.

9.2 Dentro de la clase principal crear tres clientes con los números 1, 2, 3.

• Leer el archivo de cuentas.


• Extraer las cuentas y asignarlas a los clientes ya creados.

9.3 Validar que cada archivo tenga sus respectivas cuentas:

• El cliente con número 1 debe contener 1 cuenta.


• El cliente con número 2 debe contener 2 cuentas.
• El cliente con número 3 debe contener 2 cuentas.

Validar que los métodos del cliente sigan funcionando de manera correcta.
Path
https://docs.oracle.com/javase/tutorial/essential/io/p
ath.html
Operaciones con Path
https://docs.oracle.com/javase/tutorial/essential/io/p
athOps.html
Operaciones con archivos
https://docs.oracle.com/javase/tutorial/essential/io/fil
Referencias eOps.html

Bibliográficas
Capítulo 10. Manejo de
Fechas
Objetivos
En este capítulo aprenderás:
 Clases principales del paquete java.time.

 Crear formatos con DateTimeFormatter.

 Convertir y presentar fechas.

 Manejar Zonas horarias con ZonedDateTime.


Clases principales del paquete java.time
 Las primeras clases que probablemente encontrarás al usar la nueva API
son LocalDate y LocalTime.

 Son locales en el sentido de que representan la fecha y la hora del contexto


del observador, como un calendario en un escritorio o un reloj en la pared.

 También hay una clase compuesta llamada LocalDateTime, que es la unión


de LocalDate y LocalTime.
Creando objetos de java.time
Operaciones
Operaciones
DateTimeFormatter
 La clase DateTimeFormatter en Java se usa para analizar fechas en
diferentes formatos.
 Puedes usar esta clase para formatear la fecha en un formato
específico o puedes usar las instancias predefinidas de la clase
DateTimeFormatter.
Aplicando formato DateTimeFormatter
Creando nuevo formato
Conversión de cadenas a fechas
Manejo de zonas horarias
 Una zona horaria es un conjunto de reglas que corresponden a una
región en la que la hora estándar es la misma.
 Hay alrededor de 40 de ellas.
 Las zonas horarias se definen por su diferencia con la hora universal
coordinada (UTC), se mueven aproximadamente en sincronía, pero
con una diferencia específica.
ZonedDateTime
Resumen del capítulo
La API java.time en Java proporciona una forma moderna y eficiente de
manejar fechas y tiempos, incluyendo operaciones de formato, análisis,
cálculos de duración y manipulaciones avanzadas. Esto facilita la escritura de
código más preciso y legible en aplicaciones que trabajan con fechas y
tiempos.
Evaluación Práctica 10
Hasta el momento hemos manejado las fechas en un formato de cadenas, pero ahora
cambiarás todos los atributos que representan una fecha al tipo LocalDate.

10.1 Cambia cada uno de los siguientes atributos al tipo LocalDate:

• fechaApertura (Cuenta).
• fechaCancelacion (Cuenta).
• fechaNacimiento (Cliente).

Haz los cambios necesarios en las clases relacionadas con las fechas para que funcionen de
manera correcta, por ejemplo, actualiza los métodos sets y gets, así como en los métodos de
impresión de los objetos.
Evaluación Práctica
Fechas
https://docs.oracle.com/javase/tutorial/datetime/iso/
date.html
Fechas y Tiempo
https://docs.oracle.com/javase/tutorial/datetime/iso/
datetime.html
Zonas
https://docs.oracle.com/javase/tutorial/datetime/iso/ti
mezones.html
Análisis y formateo de fechas
Referencias https://docs.oracle.com/javase/tutorial/datetime/iso/f
Bibliográficas ormat.html
Capítulo 11. Manejo de
Hilos
Objetivos
En este capítulo aprenderás a:
 Definir un hilo.

 Usar la clase Thread.

 Implementar Runnable.

 Crear pools de hilos con ExecutorService.

 Aprender a usar las interfaces Callable y Future.

 Saber qué representa la clase CyclicBarrier.

 Conocer las buenas prácticas en el manejo de los hilos.


¿Qué es un hilo?
 Un hilo es un subproceso de ejecución en un programa, también se les
llama lightweight thread (proceso ligero).
 La máquina virtual Java permite que una aplicación tenga varios
subprocesos en ejecución al mismo tiempo, dentro del contexto de
ejecución del proceso que es la JVM.
 Los hilos nos permiten realizar un mecanismo llamado multitarea.
 Solo tenemos procesos en paralelo cuando tenemos a nuestra
disposición más de un CPU en nuestro equipo.
Sin Multitarea
Con Multitarea
La clase Thread
 Hasta el momento se ha explicado para qué sirven los hilos en la vida
de los programadores.
 Una forma de usarlo en programación es dividir el trabajo en varias
tareas “simultáneas”.
 Para poder crear hilos en Java existen múltiples formas, la más común
es usar la clase Thread.
Usando la clase Thread
Usando la clase Thread (Cont.)
Ejecutando dos hilos
Salida de la ejecución de los hilos
Funcionamiento interno
Interfaz Runnable
 Esta interfaz es considerada como una interfaz funcional ya que tiene
la siguiente estructura:
Ejemplo de Runnable
Usando Runnable en Thread
Pools de Hilos la interfaz ExecutorService
 La interfaz Java ExecutorService java.util.concurrent.ExecutorService
representa un mecanismo de ejecución asíncrono que es capaz de
ejecutar tareas simultáneamente en segundo plano.
 La diferencia principal que tiene un Thread y el pool de hilos de
ExecutorService es que sus hilos son reutilizables.
Ejemplo ExecutorService
Funcionamiento interno
Pools de hilos ExecutorService
Callable y Future
 En el caso que necesites obtener el valor del resultado de la ejecución
de un hilo tienes que usar la interfaz Callable en conjunto con
Future<T>.
 Callable es una interfaz funcional con la siguiente sintaxis:
CyclicBarrier
 CyclicBarrier se utiliza para hacer que los subprocesos se esperen
entre sí.
 Se utiliza cuando diferentes subprocesos procesan una parte del
cálculo y cuando todos los subprocesos han completado la ejecución,
el resultado debe combinarse en el subproceso principal.
Buenas prácticas en el manejo de hilos
 Usar variables locales.
 Usar clases inmutables,
 Utilizar el ExecutorService del grupo de subprocesos.
 Utilizar herramientas de sincronización (CyclicBarrier).
 Utilizar una colección de lectura simultánea como:
(ConcurrentHashMap CopyOnWriteArrayList y CopyOnWriteArraySet y
BlockingQueue Deque y BlockingDeque).
 Evitar el uso de variables estáticas y campos compartidos.
Resumen del capítulo
Los threads (hilos o procesos ligeros) en Java permiten la ejecución
concurrente de tareas en un programa, mientras que la clase
ExecutorService simplifica el manejo y la programación multihilo al
proporcionar un conjunto de threads reutilizables y métodos para enviar y
controlar tareas de manera eficiente. Esto es útil para mejorar el rendimiento
y la eficiencia en aplicaciones que requieren concurrencia, al tiempo que
reduce la complejidad de la programación multihilo manual.
Evaluación Práctica 11
Para esta práctica se debe de retomar el proyecto que has hecho hasta ahora. Una de las
tareas más pesadas que podría tener nuestro proyecto es la lectura del archivo de cuentas,
conforme se vaya incrementando el número de clientes y sus respectivas cuentas.

Para esta práctica el reto es ejecutar la lectura del archivo en un hilo usando ExecutorService
y newSingleThreadExecutor().

El programa se espera que funcione de la siguiente manera:


Evaluación Práctica
11.1 Los requerimientos para esta práctica son los siguientes:

• Crear un hilo usando ExecutorService para la lectura del archivo de cuentas.txt.


• Obtener las cuentas creadas a partir del archivo usando Future<Cuenta> y
Callable<Cuenta>.
• Imprimir las cuentas obtenidas por el hilo del ExecutorService en el hilo principal main.
• Validar que la aplicación continúe funcionando correctamente.
Threads y Locks
https://docs.oracle.com/javase/specs/jls/se16/html/jl
s-17.html#jls-17.1
Procesos y Threads
https://docs.oracle.com/javase/tutorial/essential/con
currency/procthread.html
Executor y ExecutorService
https://docs.oracle.com/javase/tutorial/essential/con
currency/exinter.html
Thread Pools
https://docs.oracle.com/javase/tutorial/essential/con
Referencias currency/pools.html
Colecciones concurrentes
Bibliográficas https://docs.oracle.com/javase/tutorial/essential/con
currency/collections.html
Capítulo 12. ParallelStreams
Objetivos
En este capítulo aprenderás a:
 Utilizar el método parallelStream().

 Usar operaciones determinísticas y no determinísticas.

 Usar el método reduce con parallelStream.


Método ParallelStream()
 Java 8 introdujo la API Stream que facilita la iteración sobre
colecciones como flujos de datos.
 También es muy fácil crear transmisiones que se ejecutan en paralelo
y hacen uso de múltiples núcleos de procesador.
 Se podría pensar que siempre es más rápido dividir el trabajo en más
núcleos, sin embargo, no siempre es este caso.
ParallelStream en Java
¿Cuándo usar ParallelStream?
 Una gran cantidad de datos y muchos cálculos realizados por
elemento indican que el paralelismo podría ser una buena opción.
 Por otro lado, una pequeña cantidad de datos fuentes que se dividen
de manera desigual, costosas operaciones de fusión y una ubicación
deficiente de la memoria indican un problema potencial para la
ejecución en paralelo.
 Supongamos que deseas ordenar un mazo de cartas, ¿Que sería más
rápido y eficiente? ¿Hacerlo tu solo, dividirlo entre 4 personas, o dividir
la tarea entre 20 personas o más?
 Cuando la tarea se divide entre varios participantes, al final hay que
consolidar las tareas parciales en un resultado final.
Operaciones Determinísticas
 Un algoritmo determinístico es un algoritmo que, teniendo una entrada
particular, siempre produce la misma salida.
 El método sum(), average(), findFirst(), min(), max(), count() son
buenos ejemplos de que el orden de los factores no altera el producto.
 Esto quiere decir que sin importar cómo se realice la operación el
resultado siempre será el mismo.
Ejemplo Operaciones Determinísticas
Operaciones no Determinísticas
 En la API de Stream existe un grupo de operaciones que cambian su
resultado dependiendo del orden en el que se procesen los datos.
 A los algoritmos que cambian el resultado dependiendo del orden se
les llaman no determinísticos.
 Una operación que pertenece a este grupo sería findAny().
Ejemplo Operaciones no Determinísticas
Método reduce()
 Las operaciones de flujo de reducción nos permiten producir un único
resultado a partir de una secuencia de elementos, aplicando repetidamente
una operación de combinación a los elementos de la secuencia.
 Identidad: Un elemento que es el valor inicial de la operación de reducción y
el resultado predeterminado si el flujo está vacío.
 Acumulador: Una función que toma dos parámetros: Un resultado parcial de
la operación de reducción y el siguiente elemento del flujo.
 Combinador: Una función que se utiliza para combinar el resultado parcial
de la operación de reducción cuando la reducción se paraleliza o cuando
hay una falta de coincidencia entre los tipos de argumentos del acumulador y
los tipos de implementación del acumulador.
Ejemplo reduce()
Reducción en Paralelo
Cuando usamos flujos en paralelo, debemos asegurarnos de que
reduce() o cualquier otra operación agregada sea ejecutada en los flujos:

 asociativo: El resultado no se ve afectado por el orden de los


operandos.
 sin interferencias: La operación no afecta la fuente de datos.
 sin estado y determinista: La operación no tiene estado y produce la
misma salida para una entrada determinada.
Ejemplo reduce en paralelo
Resumen del capítulo
ParallelStream en Java permite realizar operaciones de procesamiento de
datos en paralelo de manera más eficiente, lo que puede mejorar el
rendimiento en sistemas multicore. Es una característica útil cuando se
trabaja con grandes conjuntos de datos, pero debe utilizarse con cuidado y
evaluarse en función de las necesidades específicas de la aplicación y del
hardware disponible.
Evaluación Práctica 12
El diagrama de nuestro proyecto hasta el momento es el siguiente:
Evaluación Práctica
En la práctica número siete implementamos los Streams en nuestros métodos de los
Servicios ServicioClientes y ServicioCuentas.

Los requerimientos para esta práctica son los siguientes:

12.1 Cambiar los Streams secuenciales de los métodos implementados de ServicioClientes y


ServicioCuentas a Streams paralelos.

12.2 Validar que los métodos funcionen correctamente en la clase principal.


Paralelismo
https://docs.oracle.com/javase/tutorial/collections/str
eams/parallelism.html
Reducción
https://docs.oracle.com/javase/tutorial/collections/str
eams/reduction.html
Ejemplos de uso de parallelStream
https://docs.oracle.com/javase/tutorial/collections/str
Referencias eams/examples/ParallelismExamples.java

Bibliográficas
Capítulo 13. JDBC –
Conectividad de Base de
Datos Java
Objetivos
En este capítulo aprenderás:
 Una introducción a bases de datos relacionales.

 A utilizar la base de datos MySQL de forma básica.

 La instalación de MySQL.

 Cómo crear Bases de Datos.

 A conectarse con MySQL desde Apache Netbeans.

 Cuáles son los componentes de la API de JDBC.

 Como realizar una conexión a una base de datos relacional desde


Java.
 A llevar a cabo las operaciones CRUD utilizando la API de JDBC.
Base de Datos Relacionales | Conceptos

Llave
Primaria Llave
Foránea

Motor de base
de datos
Base de Datos Relacionales | Conceptos

2 3 6
ID Nombre Apellido Salario Jefe Inmediato Departamento
100 Gabriel Guerra 50000 55 100
101 Jesús Paz 30000 100 100 4
1 102 Marco Espejo 35000 100 100
103 Ana Salgado 35000 null 5 101
Bases de Datos Relacionales | Normalización

 Normalización: Es el proceso de organizar los datos de una base de datos.


 Las bases de datos se normalizan para:
 Evitar la redundancia de datos.
 Diminuir problemas de actualización de los datos en las tablas.
 Proteger la integridad de los datos.
 Facilitar el acceso e interpretación de los datos.
 Reducir el tiempo de complejidad de revisión de bases de datos.
 Optimizar el espacio de almacenamiento.
 Prevenir la eliminación indeseada de datos.
Base de Datos Relacionales | Características

 Una Base de Datos Relacional se compone de varias tablas o relaciones.


 No hay dos tablas con el mismo nombre.
 Cada tabla tiene a su vez un conjunto de registros (renglones o filas y
columnas).
 La relación entre una tabla principal y una secundaria se lleva a cabo por
medio de llaves primarias y llaves foráneas o externas.
 La llave primaria es un identificador principal de un registro dentro de una
tabla y debe cumplir con la integridad de los datos.
 Las llaves foráneas se colocan en la tabla secundaria, estas contienen el
mismo valor que la clave primaria del registro principal; por medio de estas
llaves se establecen las relaciones.
Base de Datos Relacionales | SQL
 El lenguaje más utilizado para gestionar las bases de datos
relacionales es SQL, Structured Query Language.
 SQL es el estándar implementado por los principales motores o
sistemas de gestión de bases de datos relacionales.
 SQL es un conjunto de sentencias con las cuales los programas y
usuarios pueden accesar datos en una base de datos relacional.
 SQL cuenta con varias sentencias para una variedad de tareas, como:
 Recuperar datos, insertar, actualizar, eliminar, controlar el acceso a los datos, garantizar
la consistencia e integridad de los datos.
Bases de Datos Relacionales | SQL

Data Manipulation Language Data Definition Language

SQL
DML DDL
selec, insert, update, delete, create, alter, drop, rename,
truncate, comment

Data Control Language Transaction Control Language


DCL TCL
grant, revoke commit, rollback, savepoint
Introducción a MySQL
MySQL

 MySQL, es el sistema de administración de base de datos SQL de código


abierto más popular, es desarrollado, distribuido y respaldado actualmente por
Oracle Corporation.
 MySQL es un sistema de gestión de bases de datos.
 La base de datos MySQL soporta principalmente el modelo relacional, pero
también el No SQL.
 El software MySQL es de código abierto.
 El servidor de base de datos MySQL es rápido, confiable, escalable y fácil de
usar.
 MySQL Server funciona en sistemas cliente/servidor o embebidos.
 MySQL cuenta con una gran cantidad de contribuciones.
MySQL | Características

 Escrito en C & C++


 Multiplataforma:
 Oracle Linux, Red Hat, Centos, Solaris 11, Ubuntu, Suse, Debian, Microsoft Windows
Server, MS Windows, MacOS, etc.
 Disponibilidad de APIs multilenguaje:
 C, C++, Eiffel, Java, Perl, PHP, Python, Ruby, TCL, etc.
 Arquitectura multicapas con módulos independientes.
 Multiproceso.
 Motores de almacenamiento transaccional y no transaccional.
 Diferentes motores de almacenamiento que se ejecutan al mismo
tiempo.
MySQL | Engines

 InnoDB
 Es el almacenamiento basado en ACID, predeterminado en la versión 8.0.
 MyISAM
 Maneja tablas no transaccionales, bloqueo a nivel tabla e índices de búsqueda de texto
completo.
 Federated
 Permite el acceso a datos en tablas de base de datos remotas.
 Memory
 Maneja las tablas y datos en memoria.
mysql> show engines \G
MySQL 8.0
 Diccionario de datos
 Diccionario de datos transaccionales sobre los objetos de la base de datos.
 Previamente se almacenaban en archivos de metadatos.
 Sentencias de definición de datos atómicos (DDL atómico)
 Actualización del diccionario de datos + operación motor de almacenamiento + escrituras de
registros binarios asociadas con la operación DDL en una sola transacción atómica.
 Procesamiento de actualización
 Automatizado, ya no lo realiza el DBA con mysql_upgrade.
 Mejoras en la seguridad y gestión de cuentas
 Administración de recursos
 Creación y gestión de grupos de recursos.
 Gestión de cifrado de tablas
MySQL | instalación y configuración

1. Descargar MySQL desde aquí, Windows (x86, 32-bit), MSI Installer.


2. Selecciona no registrarte y solo descarga la versión Community, el
número de versión podría cambiar, actualmente es la 8.0.

3. Inicia el asistente de instalación.


4. Selecciona la opción de instalación Custom.
MySQL | Instalación y Configuración

Next
MySQL | Instalación y Configuración

Next
MySQL | Instalación y Configuración

Execute
MySQL | Instalación y Configuración

Execute Next
MySQL | Instalación y Configuración

Next
MySQL | Instalación y Configuración

3306
33060

Next
MySQL | Instalación y Configuración

Next
MySQL | Instalación y Configuración
MySQL | Instalación y Configuración

Next
MySQL | Instalación y Configuración

Next
MySQL | Instalación y Configuración

Execute
MySQL | Instalación y Configuración

Finish
MySQL | Instalación y Configuración

Next
MySQL | Instalación y Configuración

Next
Verificar
MySQL | Instalación y Configuración

Finish
Execute
MySQL | Instalación y Configuración

Next
MySQL | Instalación y Configuración

Finish
MySQL | Workbench
Workbench es la interface gráfica de usuario de MySQL que permite diseñar, crear y
manejar tus esquemas de base de datos y objetos, así como los datos en sí mismos y
ejecutar directamente código SQL, tiene muchas funciones adicionales.
MySQL | Shell
MySQL Shell es una herramienta de línea de comandos y una interfaz de línea de
comandos para interactuar con la de base de datos MySQL. Fue introducido como una
herramienta unificada en MySQL 8.0 y tiene muchas funcionalidades.
MySQL | Comandos net y sc
MySQL | Archivo my.ini o my.cnf

 my.ini es un archivo de configuración utilizado en la base de datos MySQL, en Linux se llama my.cnf.
 Ubicado en c:\ProgramData\MySQL\MySQL Server 8.0\my.ini o en Linux en /etc/my.cnf
 Tiene diferentes parámetros de configuración como:
 Puerto de servicio.
 Conjunto de caracteres por defecto.
 El motor de almacenamiento por defecto.
 Parámetro para establecer la rigurosidad de la instrucción SQL.
 Máximo número de conexiones.
 El tamaño de la memoria caché en el momento de la consulta.
 El total de tablas abiertas por todos los procesos.
 Número de tablas temporales en memoria.
 Etc.
MySQL | Lenguajes y Conectores

 MySQL tiene APIs para varios lenguajes de programación:


 API Java
 API C
 API PHP
 API Perl
 API C++
 API Python
 API TCL
 API Eiffel
 API Ruby
MySQL | Lenguajes y Conectores

 ODBC - MySQL Connector/ODBC


 ODBC database API en Windows & Unix
 JDBC - MySQL Connector/J
Para conectar Angular con MySQL,
 Java Driver JDBC
necesitas un servidor intermedio que
 NET - MySQL Connector/Net actúe como una API RESTful o GraphQL
para manejar las solicitudes y respuestas
 ADO.NET access para .NET entre el cliente Angular y la base de datos
 MySQL Connector/PHP MySQL
 PHP sobre Windows
API JBDC
 JDBC o Java Database Connectivity es una especificación que
desarrolló Sun Microsystems que proporciona una abstracción
estándar, es decir API o Protocolo, para que las aplicaciones Java se
comuniquen con bases de datos.
 JDBC proporciona el lenguaje estándar de conectividad y manejo de
interacción con las bases de datos relacionales desde Java.
 Se utiliza para escribir los programas necesarios para acceder a
diferentes bases de datos relacionales.
Componentes JDBC API
Conexión a una Base de Datos
Para conectarte a una base de datos debes usar la API de JDBC y
necesitas los siguientes elementos:

 Driver del proveedor: Normalmente es un JAR (Java Archive) que


debemos descargar de la página del proveedor de la base de datos.
 URL de conexión.
 Usuario.
 Password.
 Nombre de base de datos.
Conexión a MySQL en Java
INSERT
SELECT
UPDATE
DELETE
Clase PreparedStatement
 Al usar la clase PreparedStatement estás evitando que te inyecten
código en la sentencia SQL, ya que al parametrizar la consulta de la
API de JDBC te protege contra este tipo de ataques.
Ejemplo PreparedStatement
Transacciones con JDBC
 El uso de transacciones en la API de JDBC (Java Database
Connectivity) es esencial para garantizar la integridad de los datos y la
consistencia en las operaciones de base de datos.
 Concepto de Transacción: Una transacción es una secuencia de
operaciones de base de datos que se ejecutan como una unidad
atómica, esto significa que todas las operaciones se completan con
éxito o ninguna de ellas se aplica.
 Las transacciones se utilizan para mantener la integridad de los datos
y garantizar que la base de datos se mantenga en un estado
coherente.
Transacciones con JDBC
 En JDBC, las transacciones se manejan a través del objeto
Connection.
 Debes obtener una instancia de Connection para interactuar con la
base de datos y realizar operaciones dentro de una transacción.
Transacciones con JDBC
Métodos para manejar Transacciones: JDBC proporciona métodos en el
objeto Connection para el manejo de transacciones:

 commit(): Confirma la transacción actual y aplica todos los cambios en la


base de datos.
 rollback(): Cancela la transacción actual y deshace todos los cambios
realizados desde el último commit.
 setAutoCommit(boolean autoCommit): Permite habilitar o deshabilitar el
modo de autocommit. Cuando está deshabilitado (autoCommit es false), las
transacciones deben confirmarse manualmente.
Transacciones con JDBC
 Modo de Autocommit: Por defecto, el modo de autocommit está
habilitado en JDBC.
 Esto significa que cada operación de base de datos se considera una
transacción independiente y se confirma automáticamente al final de la
operación.
 Puedes deshabilitar el autocommit para agrupar varias operaciones en
una única transacción.
Ejemplo de Uso de Transacciones
try {
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mi_base_de_datos", "usuario",
"contraseña");

// Deshabilitar el autocommit
conn.setAutoCommit(false);

// Realizar operaciones de base de datos (por ejemplo, inserciones o actualizaciones)


// INSERT/DELETE/UPDATE
// Confirmar la transacción
conn.commit();
} catch (SQLException e) {
// Manejo de errores y posible rollback en caso de excepción
conn.rollback();
} finally {
// Cerrar la conexión
conn.close();
}
Resumen del capítulo
MySQL es un sistema de gestión de bases de datos relacionales popular y
versátil que se utiliza en una amplia variedad de aplicaciones. Su código
abierto, escalabilidad y comunidad activa lo convierten en una opción
atractiva para proyectos de cualquier tamaño. Además, ofrece características
avanzadas para garantizar la seguridad, la redundancia y la alta
disponibilidad de los datos.
JDBC en Java es una API esencial para la interacción con bases de datos
relacionales. Facilita la conexión, la consulta y la manipulación de datos en
bases de datos, y es ampliamente utilizado en aplicaciones Java
empresariales y de otro tipo que requieren acceso a datos almacenados en
un RDBMS.
Evaluación Práctica 13
Hasta el momento, en tu proyecto se extraen las cuentas desde un archivo.

Para la práctica de esta lección cambiaremos el archivo por una base de datos.

13.1 Usa los siguientes comandos para crear una base de datos con los mismos datos que
tenía el archivo.

drop database if exists banca;


create database banca;
use banca;
create table cuentas(numero int(10) primary key, fecha varchar(20), saldo double, interes
double, cliente int(3), tipoCuenta varchar(23));
insert into cuentas values(1234 , '12-11-2021', 323333, 2 , 1, "CA");
insert into cuentas values(123456, '10-01-2020', 54878 , 4 , 2, "CA");
insert into cuentas values(7894 , '05-08-2021', 98745 , 5 , 3, "CA");
insert into cuentas values(65478 , '08-02-2019', 98874 , 200,2, "CC");
insert into cuentas values(65447 , '21-12-2019', 10000 , 300,3, "CC");
Evaluación Práctica
Con estos comandos creaste una base de datos llamada “banca”, y como parte de ella tienes
ahora una tabla llamada “cuentas”.

La estructura de la tabla es la siguiente:


Evaluación Práctica
Los datos contenidos en la tabla “cuentas” son:
Evaluación Práctica
13.2 Realiza los siguientes requerimientos para esta práctica:

• Crea un programa en Java que se llame CuentasDAO.java para cambiar la extracción de las
cuentas desde el archivo por la extracción de las cuentas desde la base de datos.

• Usa las clases Connection, Statement, ResultSet para realizar las tareas de conexión,
creación de la sentencia y ejecución de la siguiente sentencia sql: “SELECT * FROM
CUENTAS” para llevar a cabo la consulta de todos los datos que existen en la tabla.

• Asigna las cuentas a sus correspondientes clientes.

• Valida que los métodos sigan funcionando correctamente.

13.3 Implementa las operaciones CRUD para la tabla de cuentas para llevar a cabo las
operaciones de creación, actualización y eliminación de cuentas.
Java JDBC API y su documentación
https://docs.oracle.com/javase/8/docs/technotes/gui
des/jdbc/
https://docs.oracle.com/javase/8/docs/technotes/gui
des/jdbc/jdbc_42.html
Creando una conexión con la Base de Datos
https://docs.oracle.com/javase/tutorial/jdbc/basics/c
onnecting.html
Atrapando excepciones tipo SQL
https://docs.oracle.com/javase/tutorial/jdbc/basics/s
qlexception.html
Referencias Usando Sentencias Preparadas
Bibliográficas https://docs.oracle.com/javase/tutorial/jdbc/basics/pr
epared.html
Capítulo 14. Uso de
Módulos en Java
Objetivos
En este capítulo aprenderás:
 Una introducción a la programación modular con Java.

 Cómo implementar módulos en Java.

 A evaluar las ventajas de un sistema modular.

 A utilizar las sentencias requires y exports en los módulos.

 Cómo migrar una aplicación de Java 8 a Java modular.

 El manejo de las dependencias cíclicas.


Programación Modular
 La programación modular se define como una técnica de diseño de
software que se centra en separar la funcionalidad de un programa en
módulos independientes e intercambiables.
 Cada módulo contiene todo lo necesario para ejecutar solo un aspecto
de la funcionalidad.
 Hablando de modularidad en términos de archivos y repositorios, la
modularidad puede existir en diferentes niveles:
 Bibliotecas en proyectos.
 Funciones en los archivos.
 Archivos en las bibliotecas o repositorios.
Módulos en Java
 Los módulos en Java también nos permiten añadir seguridad a los
paquetes y abrirlos de acuerdo a quién los usa.
Módulos en Java
Pareciera que no existe un gran cambio, pero podríamos resaltar los
siguientes elementos al utilizar módulos:
 Dentro de un módulo pueden existir múltiples paquetes relacionados
entre sí.
 Dentro de cada módulo existe un archivo module-info.java, utilizando
este archivo puedes controlar qué paquete se puede usar fuera del
módulo.
 Todos los paquetes dentro del módulo por default no pueden ser
utilizados fuera del módulo, a menos que se le indique lo contrario
dentro del module-info.java.
Contenido de un módulo en Java
Ventajas del sistema modular
 Aplicaciones más pequeñas y distribuibles a través de la plataforma
Java modular.

 Encapsulación de paquetes internos.

 Detección de inicio de módulos faltantes.


Usando el JDK Modular
 A partir de Java 9 toda la plataforma de Java está modularizada, esto
permite que nosotros elijamos los módulos que queremos utilizar en
nuestros proyectos, permitiendo que nuestras aplicaciones sean
mucho más pequeñas y que sólo usen lo que realmente necesitan.
Usando Módulos del JDK
requires y exports
 Estas dos palabras reservadas están relacionadas entre sí y nos
permiten controlar qué módulo usaré y a qué paquete quiero compartir.
exports
 exports paquete1 to com.netec.modulo2; Con esta línea de código
le indicamos que sólo el módulo 2 podrá utilizar el paquete1.
requires
 requires com.netec.modulo1; Con esta línea de código le estamos
indicando al módulo2 que usaremos al módulo1.
 Pero sólo podrá usar los paquetes que haya compartido el módulo1 y
en este ejemplo sólo compartió el paquete1.
Migrando Aplicación de Java 8 a Java Modular
 Ejecuta tu aplicación sin modularizar nada.
 Mueve los archivos JAR de la biblioteca de utilidades a la ruta del
módulo.
 Migra bibliotecas de utilidades internas y de terceros a módulos Java
cuando sea posible.
 Migra tus aplicaciones principales a módulos Java con nombre.
 Actualiza las bibliotecas de utilidades primero a módulos automáticos y
luego a módulos completos.
Manejo de Dependencias Cíclicas
 En el sistema modular no son permitidas las relaciones cíclicas, es
decir que módulo1 utilice al módulo2 y el módulo 2 utilice al módulo1.
Solución
 La forma en la que podemos evitar este tipo de relaciones sería
extraer los paquetes que se necesitan en ambos módulos y agregarlo
en un nuevo módulo y ahora este nuevo módulo podrá llamarse sin
ningún problema desde ambos módulos.
Resumen del capítulo
Los módulos en Java son una forma de modularizar y organizar aplicaciones
Java en unidades independientes que encapsulan clases y recursos
relacionados. Proporcionan beneficios de mantenibilidad, seguridad y gestión
de dependencias, lo que facilita la construcción y el mantenimiento de
aplicaciones Java a gran escala.
Evaluación Práctica 14
Hasta el momento el diagrama de tu aplicación es el siguiente:
Evaluación Práctica
En esta práctica debes implementar el siguiente diseño modular:
Evaluación Práctica
14.1 Los requerimientos para esta práctica son los siguientes:

• Cambiar la aplicación actual de Java a una aplicación modular.

• Validar que todas las clases se puedan comunicar entre si a pesar de que se encuentren en
diferentes módulos.

• Validar que la aplicación siga funcionando.


Entendiendo módulos en Java
https://www.oracle.com/corporate/features/understa
nding-java-9-modules.html
El módulo java.base
https://docs.oracle.com/en/java/javase/12/docs/api/j
ava.base/module-summary.html
El módulo java.se
https://docs.oracle.com/en/java/javase/11/docs/api/j
ava.se/module-summary.html
Referencias Introducción a módulos en Java
https://dev.java/learn/modules/intro/
Bibliográficas
Capítulo 15. Localización
Objetivos
Después de completar este capítulo serás capaz de:
 Describir las ventajas de la localización.
 Definir que representa una localidad.
 Leer y modificar un objeto Locale.
 Crear y leer un archivo de propiedades.
 Construir un resource boundle.
 Llamar un resource boundle desde una aplicación.
¿Qué es localización?
 La decisión de crear una versión de una aplicación internacional
regularmente sucede al inicio de un desarrollo.
 Manejo de formatos usados en la región y en el lenguaje (idioma) .
 Uso de fechas, números y formatos específicos de algunos países.
 La habilidad de conversión de datos dependiendo de la región.
Locale
 Un Objeto Locale especifica un idioma y un país.
 Idioma
 Siempre es en minúsculas.
 ISO 639
 País
 Usa ISO 3166
 Siempre es en mayúsculas.
Properties
 La clase java.util.Properties es usada para cargar y salvar valores del
tipo llave-valor.
 Puede almacenarse como un archivo de texto simple.
 El nombre del archivo termina con .properties
 El archivo puede estar en cualquier lugar.
Cargar y usar un Archivo de Propiedades
Cargar propiedades desde la línea de comandos
 La información puede pasarse a través de la línea de comandos.
 Usa la opción –D para pasar valores del tipo llave-valor.

 Para leer las propiedades obtén las propiedades usando la clase


System.
Resource Bundle
 Es una clase que aísla los datos específicos de una localidad:
 Retorna valores del tipo llave-valor.
 Puede ser una clase o un archivo .properties

 Pasos para usar:


 Crea archivos bundle para cada localidad.
 Llama una localidad específica para que cambie dinámicamente los
formatos.
Archivo Resource Bundle
 Es un archivo de propiedades que contiene una serie de valores llave-
valor:
 Cada llave identifica un componente de la aplicación.
 Los nombres de archivos especiales usan el idioma y el código de país.
 Ejemplo:
Ejemplos de archivos ResourceBundle
 Ejemplos de Francés y Chino:
Inicializando un ResourceBundle
Cambiando formatos de números
Cambiando formato de fechas
Resumen del capítulo
La localización es importante en aplicaciones que tienen usuarios en
diferentes partes del mundo, ya que permite que la aplicación se presente de
una manera familiar y útil para cada usuario, independientemente de su
ubicación. Java proporciona las herramientas necesarias para facilitar la
implementación de la localización en aplicaciones Java y garantizar una
experiencia de usuario adecuada para audiencias globales.
Evaluación Práctica 15
15.1 Escribe un programa en Java en donde se puedan cambiar de idioma las opciones de un
menú de Español a Inglés y viceversa, el menú deberá contemplar las opciones: Altas, Bajas,
Cambios, Consulta por Clave, Listado General, Cambiar a Español, Cambiar a Inglés y Salir.
Las opciones son meramente enunciativas y no deberán realizar alguna acción en particular,
solo deberá imprimir en Español que opción se eligió y hacer una pausa de 3 segundos o
esperar que se dé un <Enter> para continuar. Este programa después podría ser adaptado
para ser usado en una interfaz gráfica de usuario (GUI) o en una página web de inicio de una
aplicación.

Sugerencias: Utiliza la clase Scanner para recibir por el teclado cada una de las opciones
mencionadas, las cuales deberán ser validadas. Cada vez que se elija una opción deberá
limpiarse la pantalla y se presentará de nuevo el menú hasta que se elija la opción Salir. Usa
un ResourceBundle por cada idioma que maneje la aplicación.
Propiedades
https://docs.oracle.com/javase/tutorial/essential/envi
ronment/properties.html
Clase Locale
https://docs.oracle.com/en/java/javase/16/docs/api/j
ava.base/java/util/Locale.html
Creación de un Locale
https://docs.oracle.com/javase/tutorial/i18n/locale/cr
eate.html
Clase ResourceBoundle
Referencias https://docs.oracle.com/javase/tutorial/i18n/resbundl
Bibliográficas e/concept.html
Capítulo 16. Codificación
Segura en Java
Objetivos
Después de completar este capítulo podrás:
 Describir la seguridad de Java SE.
 Explicar las vulnerabilidades del código.
 Describir las buenas prácticas y los antipatrones.
Introducción a la seguridad de Java SE
 El lenguaje de Java y la máquina virtual proveen muchas
características que nos ayudan a mitigar errores comunes en la
programación.
 El lenguaje es “Type-safe”, y la ejecución provee una administración
automática de la memoria (Garbage Collector).
 Para minimizar los problemas de seguridad se pueden usar guías que nos
recomienda buenas prácticas.
Codificación segura en Java
 La codificación segura en Java provee una serie de buenas prácticas
que podemos seguir para lograr que nuestro código sea más seguro.

Buenas prácticas
0 Fundamentos.
1 Negación de servicio.
2 Información confidencial.
3 Inyección e inclusión.
4 Accesibilidad y extensibilidad.
5 Validación de entradas.
6 Mutabilidad.
7 Construcción de objetos.
8 Serialización y deserialización.
9 Control de acceso.
¿Qué es una vulnerabilidad?
 Definición:
 Es un flujo o debilidad que puede ser explotada para violar las políticas de
seguridad.

 Causas:
 Diseño.
 Implementaciones.
 Errores en la configuración.
¿Qué es un antipatrón?
 Un antipatrón es una mala práctica en la programación que deberías
evitar.
 Pueden parecer beneficiosos en un inicio, pero pueden causar
consecuencias a largo plazo.
 Un ejemplo de esto es la implementación de código rápido en el que no se
hagan validaciones de código.
 El uso frecuente del copy/paste en el código.
Antipatrones en Java
 Negligencia al verificar un formato de entrada.
 Entrega de permisos innecesarios en el código.
 Mal uso de las variables públicas y estáticas.
 Ignorar cambios en las superclases.
 Asumir que las excepciones son inofensivas.
 Asumir que el espacio de valores de los enteros es ilimitado.
 Asumir que una excepción en un constructor destruye el objeto.
Fundamentos

Fundamentos
0 Prefiero tener fallas obvias en lugar de no tener obvias fallas.
1 Diseña APIS para evitar problemas de seguridad.
2 Evita la duplicidad.
3 Privilegios restrictivos.
4 Establece límites de confianza.
5 Minimiza la cantidad de validaciones de permisos.
6 Encapsula métodos, atributos y clases.
Negación de servicio
 La entrada en un sistema debe verificarse para que no cause un
consumo excesivo de recursos para solicitar el servicio.
 Los recursos comunes más afectados son CPU, RAM, espacio en
disco.
Negación del servicio
1-1 Cuidar las actividades que puedan
usar una gran cantidad de recursos.
1-2 Liberar los recursos usados en todos
los casos.
1-3 Limitación de recursos que valide que
no exista un desbordamiento de
memoria.
Información Confidencial
 Los datos confidenciales deben ser leídos en el contexto en el que se
usen.
 Los datos que sean de confianza no deben exponerse para la
manipulación.
 El código privilegiado no debe ser ejecutable a través de una interfaz.

Información confidencial
1 Se debe quitar información sensible de las excepciones.
2 No registres información altamente sensible.
3 Considera purgar la información altamente sensible de la
memoria después de su uso.
Inyección e inclusión
 Una forma muy común de ataque implica hacer que un programa en
particular interprete los datos elaborados de tal manera que cause un
cambio de control imprevisto, normalmente, pero no siempre, esto
implica formatos de texto.
Inyección e inclusión
1 Generar un formato válido.
2 Evita el SQL dinámico.
3 La generación de XML y HTML requiere cuidado.
4 Evita cualquier dato que no sea de confianza en la línea de comandos.
5 Restringe la inclusión XML.
6 Ten cuidado con archivos BMP.
7 Desactiva la visualización HTML en componentes Swing.
8 Ten cuidado al interpretar código que no es de confianza.
9 Evita la inyección de valores excepcionales de punto flotante.
Accesibilidad y extensibilidad
 La tarea de asegurar un sistema se hace más fácil al reducir la
"superficie de ataque" del código.

Accesibilidad y extensibilidad
1 Limitar la accesibilidad de clases, interfaces, métodos y campos.
2 Utilizar módulos para ocultar paquetes internos.
3 Aislar código no relacionado.
4 Limitar la exposición de las instancias de ClassLoader.
5 Limitar la extensibilidad de clases y métodos.
6 Comprender cómo una superclase puede afectar el comportamiento
de la subclase.
Validación de entrada
 Una característica de la cultura de Java es que se utiliza una
verificación rigurosa de los parámetros del método para mejorar la
solidez. En términos más generales, la validación de entradas externas
es una parte importante de la seguridad.
Validación de entrada
1 Validar entradas.
2 Validar la salida de objetos que no son de confianza como entrada.
3 Definir contenedores alrededor de métodos nativos.
4 Verificar el comportamiento de la API en relación con la validación de
entrada.
Mutabilidad
 La mutabilidad, aunque parece inocua, puede causar una
sorprendente variedad de problemas de seguridad.
 Los ejemplos de esta sección se utilizan en java.util.Date ampliamente,
ya que es un ejemplo de una clase de API mutable.
 En una aplicación, sería preferible utilizar la nueva API de fecha y hora
de Java ( java.time.*) que ha sido diseñada para ser inmutable.
Mutabilidad
1 Preferir inmutabilidad para tipos de valor.
2 Crear copias de valores de salida mutables.
3 Crear copias seguras de valores de entrada mutables y subclasificables.
4 Funcionalidad de copia de soporte para una clase mutable.
5 No confiar en la igualdad de identidad cuando se anule en objetos de referencia de entrada.
6 Tratar el paso de entrada a un objeto que no es de confianza como salida.
7 Tratar la salida de un objeto que no es de confianza como entrada.
8 Definir métodos de contenedor como entorno al estado interno modificable.
9 Hacer que los campos estáticos públicos sean finales.
10 Asegurar que los valores de campo finales estáticos públicos sean constantes.
11 No exponer estáticas mutables.
12 No exponer colecciones modificables.
Construcción de objetos
 Durante la construcción, los objetos se encuentran en una etapa
incómoda donde existen, pero no están listos para su uso, tal situación
presenta algunas dificultades más, además de las de los métodos
ordinarios.
Construcción de objetos
1 Evitar exponer constructores de clases sensibles.
2 Evitar la construcción no autorizada de clases sensibles.
3 Defensa contra instancias parcialmente inicializadas de clases no
finales.
4 Impedir que los constructores llamen a métodos que se pueden
anular.
5 Defensa contra la clonación de clases no finales.
Serialización y Deserialización
 En Java la Serialization proporciona una interfaz para las clases que
eluden los mecanismos de control de acceso a campos del lenguaje
Java, como resultado, se debe tener cuidado al realizar la serialización
y la deserialización.
 Además, la deserialización de datos que no son de confianza debe
evitarse siempre que sea posible y debe realizarse con cuidado
cuando no pueda evitarse.
Serialización y Deserialización
Serialización y Deserialización
1 Evitar la serialización para clases sensibles a la seguridad.
2 Proteger datos confidenciales durante la serialización.
3 Ver la deserialización igual que la construcción de objetos.
4 Duplicar las comprobaciones relacionadas con la seguridad realizadas en una clase durante la
serialización y deserialización.
5 Comprender los permisos de seguridad otorgados a la serialización y deserialización.
6 Filtrar datos seriales no confiables.
Control de acceso
 Aunque Java es en gran medida un lenguaje de capacidad de objetos,
se utiliza un mecanismo de control de acceso basado en pilas para
proporcionar APIs más convencionales de forma segura.
Resumen del capítulo
Java SE aborda la seguridad a través de políticas de seguridad, controles de
acceso, clases y APIs seguras, así como con actualizaciones regulares,
configuración personalizable y una variedad de herramientas y prácticas de
seguridad. Es importante que los desarrolladores y administradores de
sistemas sigan las mejores prácticas de seguridad al diseñar, desarrollar y
ejecutar aplicaciones Java para garantizar un entorno seguro y protegido.
Evaluación Práctica 16
Se requiere validar si nuestra aplicación cumple con las directrices y buenas prácticas de
seguridad recomendadas para Java.

16.1. Anota que directrices de seguridad son cumplidas en tu proyecto.

16.2. Identifica las directrices que le hacen falta al proyecto.

16.3. ¿Se requieren cambios en el proyecto para mejorar la seguridad?. Explica tu respuesta.
Secure Coding Guidelines for Java SE
https://www.oracle.com/java/technologies/javase/se
ccodeguide.html

Referencias
Bibliográficas
Capítulo 17. Maven
Objetivos
Después de completar este capítulo podrás:
 Describir que es Maven y su uso.
 Descargar e instalar Maven.
 Conocer la organización de archivos de un proyecto.
 Saber el uso y estructura de los archivos de configuración de Maven.
 Revisar las fases de construcción de un proyecto.
 Aprender el manejo de las dependencias.
 Crear un proyecto básico con Maven.
Maven
 Es una herramienta Open Source desarrollada en Java por la Apache
Software Foundation.
 El objetivo de esta herramienta es facilitar y estandarizar la
organización y la construcción de proyectos de software,
principalmente para proyectos destinados a la máquina virtual de Java.
 Simplifica las tareas de compilación y construcción de aplicaciones de
software.
 Incorpora una administración de dependencias con acceso a los
repositorios públicos de Maven con millones de librerías disponibles
incluyendo todas las versiones de cada una de ellas.
Instalación
 Accede a la página oficial del proyecto Maven
https://maven.apache.org/ y descarga la última versión estable, esta
se ofrece en varios formatos y plataformas, aquella que tiene la
extensión Zip será suficiente en la mayoría de los casos.
 En Windows se puede utilizar el instalador que realiza la instalación y
configuración automática en el sistema operativo.
 Si la configuración es correcta, desde una terminal de comandos
puedes invocar a Maven a modo de prueba con la siguiente instrucción:
mvn -version
 Puedes dar el comando mvn –help para ver las opciones disponibles.
Organización de archivos
Estructura de directorios y archivos
Maven define que todo proyecto Java, ya sea para construir una librería
o para una aplicación, debe tener la siguiente estructura de directorios en
el sistema de archivos:
 pom.xml: Archivo de descripción, ubicado en la raíz del proyecto. En él se
indica su nombre, la ubicación que tendrá éste en el repositorio de binarios,
las dependencias que necesita para compilar, para ejecutar o para lanzar los
test. También se especifica si se hará uso de plugins.
 src/main/java: Directorio en donde se ubicarán los archivos Java del
proyecto que serán compilados y formarán parte del binario resultante. A
partir de ese directorio es donde se tendrán en cuenta los paquetes de los
archivos Java. Por ejemplo, el archivo fuente de la clase
org.proyecto.Persona se ubicará en src/main/java/org/proyecto/Persona.java.
Estructura de directorios y archivos
 src/main/resources: Permite añadir recursos que también se
incorporarán dentro del binario resultante, pero que no deben ser
compilados. Por ejemplo, los archivos con extensión .properties, XML
o imágenes.
 src/test/java: Directorio para colocar las fuentes Java que únicamente
se usarán en la ejecución de los test unitarios. El contenido de este
directorio no será empaquetado en el binario final.
 src/test/resources: Necesario si para la ejecución de los tests se
utilizan otros recursos como archivos XML o CSV con datos de prueba
para verificar los algoritmos. Los archivos incluidos no serán
empaquetados en el contenido final.
Estructura de directorios y archivos
 target/classes: En este directorio se almacenarán las clases Java
resultantes de la compilación de las fuentes almacenadas en
src/main/java.
 target/<proyecto.jar>: Típicamente los proyectos generarán un
binario con el contenido de target/classes más src/main/resources en
un único archivo empaquetado con extensión jar. Si el proyecto es una
aplicación, éste contendrá además todas las dependencias dentro de
él para que se disponga de todo lo necesario a la hora de ejecutar la
aplicación, formando un archivo denominado fat-jar.
Fases de Construcción
 Una vez definido cómo deben organizarse los archivos fuente que
constituyen un proyecto, el siguiente paso es invocar a Maven para que
pueda realizar el proceso de construcción del proyecto.
 Maven tiene presente las dependencias entre módulos que puede haber, así
que, si se trata de un proyecto modular, el orden de construcción de los
módulos se realizará en el orden correcto que permita satisfacer las
dependencias.
 La construcción de cada módulo individual se realiza de la misma manera
que se hace sobre un proyecto simple, por tanto, ya sea para un módulo o
para un proyecto simple, Maven tratará de construir el módulo o proyecto,
pasando siempre por las siguientes fases en el orden que se indica a
continuación en la siguiente diapositiva:
Fases de Construcción
 validate: Valida que el proyecto sea correcto y que toda la información
necesaria esté disponible según la especificación de los POMs.
 compile: Compila el código fuente del proyecto revisando todos los
directorios src/main/java, alojando los archivos .class en
target/classes.
 test: Prueba el código fuente compilado utilizando el marco de prueba
unitario indicado en el POM, normalmente JUnit. En esta fase se lanza
la ejecución de todos los tests. Si el resultado de alguno de ellos no es
correcto se interrumpe la construcción.
 package: Recoge el código compilado y lo empaqueta en su formato
distribuible, normalmente como un archivo del tipo <application>.jar.
Fases de Construcción
 verify: Ejecuta cualquier comprobación de los resultados de las
pruebas de integración para garantizar que se cumplan los criterios de
calidad.
 install: Instala el paquete en el repositorio local, para usarlo como
dependencia en otros proyectos locales.
 deploy: Copia el binario construido en el repositorio remoto, para
compartirlo con otros desarrolladores y proyectos. Esta fase requiere
que se indique la URL del repositorio donde desplegar, así como
también las credenciales a usar en caso necesario.
Fases de Construcción
 clean: (opcional) Si se invoca manualmente, Maven eliminará todos
los recursos generados durante la compilación y el empaquetado,
borrando el directorio target.
 site: (opcional) Produce un informe en HTML acerca del proyecto
mostrando la documentación de la API de Javadoc y estadísticas
según las herramientas de análisis que se hayan configurado.
Ejemplos de comandos en Maven
Manejo de Dependencias
 Maven viene con unos repositorios públicos donde se despliegan la
mayoría de las librerías Open Source del ecosistema de Java, para
hacer uso de cualquiera, bastará con indicar una nueva dependencia
en el POM del proyecto.

 Cuando el proyecto requiere de una dependencia, Maven irá a


buscarlo al repositorio local, es un archivo con extensión .jar, y tratará
de descargarlo de Internet buscando en los repositorios públicos, si lo
encuentra, guardará una copia local para que esté disponible para la
siguiente vez.
Manejo de Dependencias
 El directorio por defecto del repositorio local suele estar en:
<home_usuario>/.m2/repository.

 Puede indicarse una ruta alternativa en el archivo de configuración de


Maven: <home_usuario>/.m2/settings.xml.

 El usuario es libre de eliminar el contenido de este directorio,


provocando que Maven tenga que descargar de nuevo las
dependencias necesarias.
Ámbitos de uso “scopes”
El ámbito se indica en el atributo <scope> en el archivo POM.XML y
permite separar aquellas dependencias que son necesarias para
compilar, de otras que serán sólo requeridas durante la ejecución del
aplicativo, scopes:
 compile: Es el ámbito por defecto. Se refiere a las dependencias ordinarias
que son necesarias tanto para la compilación como para la ejecución. Por
tanto, deberán ir acompañando al binario de la aplicación final.
 provided: Dependencias necesarias para compilación y ejecución al igual
que en el ámbito compile, la diferencia es que no hace falta que se añadan
al binario de la aplicación y se consideran externas. Es útil cuando se
despliega una aplicación en un servidor de aplicaciones el cual ya dispone
de las librerías necesarias.
Ámbitos de uso “scopes”
 runtime: Hace referencia a aquella que no es necesaria para la compilación,
pero sí debe ir acompañando al binario de la aplicación final puesto que la
ejecución del programa requerirá alguna funcionalidad de la librería citada.
 test: Reservado para aquellas otras que únicamente son requeridas para
realizar las pruebas de test unitarios, por lo que no son necesarias ni para la
compilación ni para la ejecución. No acompañarán al binario final.
 system: A efectos prácticos es similar a compile, con la salvedad de que el
archivo JAR es proporcionado manualmente por el programador, indicando
la ruta del archivo. No será necesario que Maven lo resuelva como
dependencia usando el repositorio local.
Ámbitos de uso “scopes”
 import: Sirve para importar todas las dependencias definidas en otro
artefacto de tipo POM. Requiere que las dependencias estén citadas en la
sección del XML denominada <dependencyManagement> de este segundo
POM.

Para ver el resultado de la resolución de los requerimientos debe ejecutarse el


siguiente comando:
Primera Aplicación con Maven
 La manera más sencilla de realizar una primera aplicación con Maven y Java
es invocar al asistente de Maven para que cree un esqueleto de aplicación.
 Para ello necesitas pasarle el grupo y el nombre del project (artifactId) al
asistente que puede invocarse desde la terminal.
 Por ejemplo, si queremos crear un proyecto con el grupo: org.eadp y
artifact:my-app ejecutaremos el siguiente comando:
Primera Aplicación con Maven
 El proyecto puede ser importado sin ningún problema desde cualquier editor
de programación de Java con soporte para Maven.
 Prueba realizar la construcción del proyecto con mvn package para ver qué
sucede.
Resumen del capítulo
Maven es una herramienta de gestión de proyectos ampliamente
utilizada en el mundo del desarrollo Java, que simplifica tareas como
el manejo de dependencias, la construcción y la distribución de
proyectos. Su estructura y filosofía de convención sobre configuración
ayudan a estandarizar proyectos, facilitando la colaboración y el
control de proyectos de software.
Evaluación Práctica 17
17.1 Crea un proyecto en Java con Maven que imprima “Hola Mundo con Maven!!!”
17.2 Prueba y ejecuta tu proyecto desde la línea de comandos.
Maven, sitio oficial
https://maven.apache.org/
Creando un proyecto en Netbeans usando Maven
https://www.jc-mouse.net/java/aplicaciones-java-
con-maven

Referencias
Bibliográficas
Capítulo 18. Optimización
y Depuración en Java
Objetivos
Después de completar este capítulo podrás:
 Describir que es Depuración y Optimización de un programa en Java.
 Aprender a utilizar el depurador que viene integrado en Netbeans.
 Aprender a utilizar el perfilador que viene integrado en Netbeans.
Optimización y Depuración en Java
 La optimización y depuración son dos aspectos fundamentales en el
desarrollo de aplicaciones en Java para garantizar que el software
funcione de manera eficiente y sin errores.

Optimización en Java:

 Rendimiento: La optimización se enfoca en mejorar el rendimiento de


una aplicación Java para que se ejecute de manera más eficiente.
Esto incluye la optimización de algoritmos, el uso eficiente de recursos
como la memoria y la CPU, y la reducción de cuellos de botella.
Optimización y Depuración en Java
 Perfiles de Rendimiento: Los perfiles de rendimiento se utilizan para
identificar áreas de una aplicación que son lentas o ineficientes.
Herramientas como VisualVM y YourKit pueden ayudar a recopilar
datos de rendimiento y analizarlos para identificar problemas.

 Uso de Herramientas: Java ofrece una variedad de herramientas de


perfilamiento y diagnóstico, como JVisualVM, JProfiler y otros, que
permiten evaluar el rendimiento de una aplicación y encontrar áreas
que necesitan optimización.
Optimización y Depuración en Java
 Técnicas de Optimización: Las técnicas de optimización incluyen el
uso de estructuras de datos eficientes, la minimización de la
duplicación de cálculos, la gestión adecuada de la memoria (como la
recolección de basura) y la paralelización de tareas cuando sea
posible.

 Pruebas de Rendimiento: Las pruebas de rendimiento se utilizan


para verificar cómo se comporta una aplicación bajo diferentes cargas
y condiciones. Esto ayuda a identificar problemas de rendimiento antes
de que la aplicación llegue a producción.
Optimización y Depuración en Java
Depuración en Java:

 Identificación de Errores: La depuración es el proceso de identificar y


corregir errores en una aplicación Java. Estos errores pueden incluir
fallos de programación, excepciones no controladas y
comportamientos inesperados.
 Uso de Depuradores: Las herramientas de depuración, como el
depurador de Eclipse o el depurador de línea de comandos de Java
(jdb), permiten inspeccionar el estado de la aplicación en tiempo de
ejecución, establecer puntos de interrupción y seguir la ejecución del
código paso a paso.
Optimización y Depuración en Java
 Impresión de Mensajes de Depuración: A menudo, se utilizan
declaraciones de impresión (por ejemplo, System.out.println()) para
mostrar mensajes de depuración y variables en la consola durante la
ejecución para comprender el flujo del programa y los valores de las
variables. No se debe dejar este código de apoyo en producción.

 Manejo de Excepciones: La captura y el manejo adecuado de


excepciones son esenciales para evitar que los errores detengan la
ejecución de una aplicación. Las excepciones no manejadas pueden
provocar bloqueos inesperados.
Optimización y Depuración en Java
 Pruebas Unitarias: Las pruebas unitarias son un enfoque proactivo
para la depuración al escribir casos de prueba para funciones y
métodos específicos antes de que ocurran errores. Las herramientas
como JUnit facilitan la creación de pruebas unitarias.

 Análisis de Stack Trace: Cuando se produce una excepción, el


análisis del stack trace proporciona información sobre la ubicación y la
causa del error, lo que ayuda en la corrección.
Resumen del capítulo
La optimización se enfoca en mejorar el rendimiento y la eficiencia de
una aplicación Java, mientras que la depuración se centra en
identificar y corregir errores y comportamientos inesperados. Ambos
procesos son esenciales en el desarrollo de software de calidad y
funcionamiento eficiente en Java.
Evaluación Práctica 18
18.1 Usando el Depurador (Debugger) de Netbeans ejecuta paso a paso el programa
principal de tu aplicación BancaElectronica, dándole seguimiento a los métodos que
se van invocando durante la ejecución del código revisando el estado de las
variables.

18.2 Utilizando el Perfilador (Profiler) de Netbeans, observa y evalúa los recursos que
está utilizando la aplicación de BancaElectronica, como es uso de memoria, hilos en
ejecución, etc.
¿Qué deduces de lo observado y analizado?. Elabora un resumen con tus
conclusiones.
Depuración de programas con NetBeans
https://javiergarciaescobedo.es/programacion-en-
java/28-programacion-estructurada/114-depuracion-
de-programas-con-netbeans
Profiling de Java en NetBeans
https://omniumpotentior.wordpress.com/2009/08/23/
profiling-de-java-en-netbeans/
Referencias
Bibliográficas
¡Gracias!
¿Dudas o comentarios?

También podría gustarte