03 Programación Básica Con Java
03 Programación Básica Con Java
Programación
Lenguaje de Programación
Un lenguaje de programación es una “estructura que, con una cierta base sintáctica y semántica,
imparte distintas instrucciones a un programa de computadora” (Perez y Merino, 2009).
Un lenguaje de programación está compuesto por:
• Símbolos
• Reglas sintácticas y Semánticas
• Estructura
• Significado
• Elementos y expresiones
Existen muchas razones por las cuales Java es una buena opción para iniciarse en el desarrollo
de aplicaciones. Como programadores es necesario conocer cuáles son las novedades
principales en los lenguajes de programación que más se utilizan para poder dar soluciones
tecnológicas punteras a nuestros clientes. Sin embargo, medir cuáles son, a nivel global, no es
una tarea sencilla de cuantificar.
Existen múltiples herramientas en Internet que han diseñado algoritmos para medir, de una
manera más o menos fidedigna, cuáles son aquellos lenguajes más utilizados y que disponen de
una comunidad de desarrolladores más grande detrás que los soportan y desarrollan. Entre
ellos, uno de los más conocidos es el índice TIOBE.
El índice TIOBE (TIOBE, The Importance of Being Earnest) es un informe mensual que elabora y
publica la empresa TIOBE Software BV. TIOBE Software BV es una empresa radicada en
Eindhoven (Holanda) que se ha encargado de desarrollar y mejorar desde el año 2001 un
algoritmo basado en la ejecución de infinidad de consultas (queries) en los mayores motores de
búsqueda del mundo (Google, MSN, Yahoo!, Baidu, Wikipedia o YouTube, entre otros). Con los
resultados obtenidos, su algoritmo es capaz de cuantificar el uso en el mundo de los distintos
lenguajes de programación. Es necesario resaltar que, en ningún caso, esta clasificación se basa
en la calidad de uso de unos u otros lenguajes, simplemente cuantifica su uso y los clasifica de
más a menos utilizados.
La Figura 1 muestra que al momento de escribir este apunte (2020) el lenguaje de programación
sobre el cual más se realiza consulta es Java. Esto supone que existe una gran cantidad de
soporte para que uno pueda aprender el lenguaje de forma autodidacta (algo que se valora en
esta materia)
Complementar los resultados del índice TIOBE con otras clasificaciones que existen en la red es
necesario para poder tener una visión global más realista. Un buen indicador complementario a
TIOBE es GitHut, un script open source que permite analizar los archivos de estadísticas que
tiene disponibles GitHub sobre los repositorios que aloja y realiza una clasificación similar a la
que hace TIOBE basada en diferentes eventos como el número de repositorios activos o el
número de commits. Como puede imaginar la cantidad de proyectos basados en aplicaciones
que utilizan la tecnología Java es considerable. Se puede afirmar que Java es una tecnología
madura, de gran uso y con múltiples aplicaciones. Su línea de aprendizaje resulta moderada
Existen diferentes programas comerciales que permiten desarrollar código Java. Los IDE’s
(Integrated Development Environment), tal y como su nombre indica, son entornos de
desarrollo integrados. En un mismo programa es posible escribir el código Java, compilarlo y
ejecutarlo sin tener que cambiar de aplicación. Algunos incluyen una herramienta para realizar
Debug gráficamente, frente a la versión que incorpora el JDK basada en la utilización de una
Consola bastante difícil y pesada de utilizar. Estos entornos integrados permiten desarrollar las
aplicaciones de forma mucho más rápida, incorporando en muchos casos bibliotecas con
componentes ya desarrollados, los cuales se incorporan al proyecto o programa. Estas
herramientas brindan una interfaz gráfica para facilitar y agilizar el proceso de escritura de los
programas.
Si lo que se desea es aprender a utilizar Java cualquier entorno de programación resulta
conveniente. En los ejemplos usados en este apunte se han utilizado Sprint Tool Suite y
Netbeans. La configuración de ambos entornos se muestra a través de los vídeos tutoriales.
Aplicaciones Java
Java es la base para prácticamente todos los tipos de aplicaciones de red, además del estándar
global para desarrollar y distribuir aplicaciones móviles y embebidas, juegos, contenido basado
en web y software de empresa. Java es aplicado en un amplio rango de dispositivos desde
portátiles hasta centros de datos, desde consolas para juegos hasta súper computadoras, desde
teléfonos móviles hasta Internet. Al momento de escribir este apunte en el sitio java.com se
mencionan estos impresionantes datos:
• El 97% de los escritorios empresariales ejecutan Java.
• Es la primera plataforma de desarrollo.
• 3 mil millones de teléfonos móviles ejecutan Java.
• El 100% de los reproductores de Blu-ray incluyen Java.
Donde las porciones encerradas entre corchetes indican que son opcionales. Además, dentro de
estos corchetes la barra vertical indica que sólo se pueden optar por alguna de las opciones
disponibles.
Como se ve, lo único obligatorio es la palabra reservada class y el nombre que se le debe
asignar a la clase. A medida que se avance sobre el desarrollo de aplicaciones usando el lenguaje
se estudiarán todas las opciones que involucran la definición de clases.
Por ejemplo, se podría declarar la clase Perro de la siguiente manera
Figura 2. Ejemplos de definición de clases que cumplen la nomenclatura para sus nombres
Relación entre el nombre de las clases y los archivos .java donde se almacenan
Las clases en Java son definidas en archivos de texto. Estos archivos tienen extensión .java. El
nombre del archivo debe coincidir con el nombre de la clase definida. Por lo tanto, para el primer
ejemplo indicado en la Figura 2 existirá un archivo con el mismo nombre, es decir
Java permite que se definan más de una clase en un único archivo con extensión .java. Cuando
se presenta esta situación el nombre del archivo debe coincidir con el nombre de la única clase
que se haya definido como public, esto es, solo puede existir una clase pública en un archivo
.java. En la Figura 3 se observan ejemplos de definiciones válidas e inválidas de clases en archivos
.java. En el primer ejemplo el archivo Persona.java posee la definición de dos clases. Debido a
que la clase Persona posee el modificador de acceso public, el archivo contiene una
definición válida de clases. En el segundo ejemplo, el archivo Persona.java posee la definición
de dos clases. Esta definición es inválida porque Java requiere que al menos una de esas clases
sea public (que además debería ser Persona, por cuanto el nombre del archivo debe
coincidir con la clase public). Por último, el tercer ejemplo tampoco se corresponde con una
definición válida, por cuanto la clase definida como public no se llama igual que el archivo.
Los paquetes
Los paquetes permiten organizar los archivos .java (y en consecuencia las clases) en categorías
que representen características comunes entre las clases. No pueden existir dentro de un
paquete clases con el mismo nombre, pero si es posible que existan clases con el mismo nombre
en diferentes paquetes. Los paquetes se pueden utilizar para ocultar clases evitando que otros
programas o paquetes accedan a clases que son de uso exclusivo de una aplicación determinada,
ya que por defecto las clases de un paquete solo reconocen las clases que se hallan en el mismo
paquete. Al organizar archivos .java en paquetes se proporciona un mecanismo sencillo y
homogéneo para acceder a clases generadas por otros programadores (usando la sentencia
import). Físicamente son carpetas o directorios que alojan archivos .java. La sentencia
package crea y/o indica a que paquete pertenece la clase de un archivo .java. En caso de que
un archivo .java sea definido en un paquete, la sentencia package debe ser la primera línea de
código generada. Solo puede existir una sentencia package por archivo .java, tal como se
observa en la Figura 4.
a) Los tipos primitivos: son definiciones dentro del lenguaje que no son objetos. Todos los
tipos numéricos están firmados (esto significa que a pesar de no ser objetos representan
el mismo tipo y alcance en cualquier plataforma que se ejecute). Para lograr esto, al
definir una variable con un tipo primitivo, el lenguaje almacena en memoria un espacio
de memoria, este espacio de memoria permite representar el rango de valores que se
le puede asignar a la variable según el tipo de datos primitivo usado. Esto significa que
al declarar una variable primitiva se asume que consumirá memoria, aunque no se use
la misma desde el principio de ejecución del programa. Debido a que se le asigna un
espacio en memoria al momento de declararse, es necesario asignarle un valor. Por
tanto, los primitivos poseen valores por defecto según el tipo de dato. La Figura 6 refleja
los tipos primitivos existentes.
b) Los tipos referencia: en Java los objetos, se crean (instancian) a partir de clases. Estos
objetos se almacenan en espacios de memoria. Java gestiona la dirección en memoria
de estos objetos. Para acceder a ellos Java asigna a cada objeto creado una “referencia”.
Esta referencia, conceptualmente hablando es similar a la dirección de una casa. Para
ubicar una casa recurrimos a la dirección. La referencia de un objeto permite acceder al
objeto en memoria. Los elementos que permiten generar instancias (objetos) son las
clases de la biblioteca de Java, las clases creadas por los programadores, las interfaces,
los arreglos y las colecciones. En definitiva, los tipos referencias son los objetos que se
crean a partir de las entidades mencionadas en la oración precedente. Más detalles
sobre el funcionamiento en memoria de las referencias se verán más adelante.
El operador new reserva espacio en memoria para contener un objeto de tipo Punto y devuelve
una referencia que se asigna a unPunto. Se puede afirmar que la referencia al objeto es la
variable unPunto. En este caso se ha usado el constructor por defecto. A partir de aquí, se puede
acceder al objeto a través de su referencia. Es posible, por tanto, tener varias referencias al
mismo objeto. Preste atención al siguiente fragmento de código:
Esto generará que se cree únicamente objeto en memoria que es referenciado por las variables
unPunto y otroPunto tal como se observa en la siguiente imagen
Donde:
• Especificaciones: opcional. Permite indicar el modificador de acceso del método, el cual
podrá optar entre los valores [public |private |protected | (si no se coloca
nada=default)]. Normalmente se utilizará el valor public, el cual indicará que el
método estará disponible para ser utilizado por cualquier entidad que lo requiera.
• tipoDevuelto: este valor es obligatorio. Permite indica si el método devolverá un valor
o no. En Java si se desea que el método devuelva un valor se debe indicar el tipo de dato
acciones que puede realizar una calculadora se halla aquella que posibilita sumar
números.
• Lista de parámetros: observe que en este caso el método sumar recibe dos parámetros:
numero1 y numero2, ambos de tipo int. Los valores de estos parámetros son los que
sumará la calculadora.
• return: observe que se ha usado la palabra reservada return. A la derecha de esta
se ha realizado la suma de los parámetros. Por tanto, return hará que el método
devuelva el resultado de esa suma. Observe además que al sumar dos números enteros
se obtiene otro valor de tipo entero. Este valor es el que se devuelve y debe
obligatoriamente coincidir con el tipo de datos indicado por el modificador de acceso
(tipoDevuelto)
También observe el ámbito del método: siempre se define dentro del ámbito de una clase (sino
Java lo interpretará como un error [no pueden definirse métodos fuera de una clase]) y un
método tiene su propio ámbito delimitado por las llaves del método (por tanto el método inicia
en la línea 5 con la llave { y finaliza en la línea 7 con la llave } ).
El Método main()
El punto de arranque de una aplicación JAVA JSE se realiza desde alguna clase que posea el
método main(). Cuando la Máquina Virtual de JAVA (JVM, en inglés) halle este método en alguna
de las clases, ejecutará el código existente en ella. Es importante tener claro que el método
main() no es el elemento principal en el desarrollo del programa. El programa, de acuerdo con
el paradigma de programación orientada a objetos, se desarrolla mediante la interacción entre
objetos por lo que el objetivo de este método normalmente es iniciar el programa y delegar el
comportamiento a los distintos los objetos correspondientes. Para entender la nomenclatura de
este método observe el siguiente ejemplo:
Con la información que ha recibido hasta este momento debería poder distinguir claramente los
siguientes aspectos:
En la línea 7 se crea un objeto, cuya referencia tiene por nombre unaCalculadora. Aquí
es donde se observa que se delega el comportamiento del programa a los objetos
intervinientes.
En la línea 8 se muestra la forma en que el lenguaje Java permite que a un objeto se le
pida que ejecute un método. Si bien este aspecto se detallará en mayor profundidad al
momento de estudiar la forma en que se invocan los métodos, se puede intuir que se le
está pidiendo al objeto unaCalculadora que sume dos argumentos: 5 y 7. El resultado
de la ejecución de este método se asigna a una variable de tipo entero denominada
resultado.
En la línea 9 se utiliza el método println(), el cual permite visualizar por pantalla aquello
que se envié como argumento (es decir aquello que se coloque entre los paréntesis del
método)
Observe que:
Cuando vayamos a dar un nombre a una variable deberemos de tener en cuenta una serie de
normas. Es decir, no se admite como buena práctica de programación colocar cualquier nombre
a una variable:
• Los identificadores son secuencias de texto unicode, sensibles a mayúsculas cuya primer
carácter solo puede ser una letra, número, símbolo $ o subrayado _ . En la práctica el
símbolo $ no es utilizado por convención.
• Es recomendable que los nombres de los identificadores sean legibles y no acrónimos
que no se puedan interpretar o que den lugar a una ambigüedad de interpretación al
leer. Esto facilitará la documentación y autodocumentación de los mismos. Además,
estos identificadores nunca podrán coincidir con las palabras reservadas.
• Algunas reglas no escritas, pero que se han asumido por convención son:
1. Los identificadores siempre se escriben en minúsculas. (ej. nombre). Y si son dos o
más palabras, el inicio de cada siguiente palabra se escriba en mayúsculas (ej.
nombrePersona)
2. Si el identificador implica que sea una constante, dicho nombre se suele escribir en
mayúsculas (ej. LETRA). Y si la constante está compuesta de dos palabras, estas se
separan con un subrayado (ej. LETRA_PI).
Una vez que se crean las clases y se definen los métodos necesarios, para poder disponer de los
mismos es necesario:
1) ejecutar la aplicación,
2) crear objetos a partir de esas clases y finalmente
3) invocar los métodos a ejecutar ejecuten sus métodos.
Algunos objetos requerirán invocar los métodos de otros objetos. Para que esto pueda ser
posible los métodos a invocar deben ser públicos (public). Esos métodos estarán disponibles
para todos los otros objetos únicamente si han sido definidos como públicos. De esta forma
estos métodos son considerados “Servicios”. La forma en la cual un objeto puede invocar un
servicio está definida por un conjunto de reglas que se conocen con el nombre de Protocolo de
mensajes de JAVA.
2. Para que un objeto pueda solicitar un método de otro objeto debe hacerlo de la
siguiente forma: Nombre_objeto . nombre_método();
Se proponen los siguientes ejemplos para verificar el funcionamiento del protocolo de mensajes
de Java:
Ejemplo 1: Dados dos números enteros numeroA y numeroB, utilice un objeto de la clase
Calculadora para obtener
𝑛𝑢𝑚𝑒𝑟𝑜𝐴 + 𝑛𝑢𝑚𝑒𝑟𝑜𝐵
𝑟𝑒𝑠𝑢𝑙𝑡𝑎𝑑𝑜 =
𝑛𝑢𝑚𝑒𝑟𝑜𝐴 − 𝑛𝑢𝑚𝑒𝑟𝑜𝐵
Definición de la clase Calculadora
en el paquete demoJSE
Posee dos métodos sumar() y
restar()
Ambos métodos poseen dos
parámetros de tipo entero.
Ambos parámetros devuelven
como resultado una variable de
tipo entero que almacena los
resultados.
En este ejemplo se crean dos variables enteras con sus respectivos valores de inicialización.
Luego se crea un objeto de tipo Calculadora (línea 10).
Observe que tanto la base como la altura se obtienen usando los métodos sumar() y restar()
del objeto unaCalculadora (requisito del problema).
El resultado de cada uno de estos métodos se guarda en las variables base y altura
respectivamente.
En la línea 18 se crea un nuevo objeto de tipo Rectángulo.
Se utiliza este objeto para calcular el área del rectángulo enviando al método calcularArea()
los argumentos representados por las variables base y altura.
Finalmente se muestra el resultado por consola.
Principal
altura= restar(numeroA, numeroB)
Cuando se profundice sobre el paradigma orientado a objetos cobrará mayor relevancia esta
manera de trabajar: Un programa principal desde el cual se instancian objetos que “colaboran”
para realizar el objetivo de la aplicación. Esta colaboración consiste en que los objetos solicitarán
la ejecución de los servicios de otros objetos y de esa manera cada uno contribuirá a la
consecución de la finalidad del programa.
Una vez que la variable ha sido eliminada, no se puede utilizar. Dicho de otro modo, no se puede
utilizar una variable más allá del bloque en el que ha sido definida. El ámbito de las variables
está determinado por el bloque de donde se declaran y todos los bloques que estén anidados
por debajo de este.
En los métodos el máximo nivel de ámbito para las variables es el cuerpo del método. Si las
variables son definidas en la lista de parámetros, su ámbito es todo el método.
Si las variables son definidas en el cuerpo del método su ámbito también es el cuerpo del
método.
Si las variables son definidas dentro de un bloque delimitado por estructuras de control (que se
verán más adelante) o por otro conjunto de sub bloques de código (delimitados por { y }) su
ámbito es ese bloque de código.
Nota importante:
Si bien Java sigue la modalidad de lenguaje fuertemente tipado, a partir de la versión 8 introdujo
el concepto de variables lambda y en Java 9 y 10 se asentó la posibilidad de definir variables
usando la sentencia var y aplicando las inferencias de tipos. Este aspecto es una fuerte evolución
del lenguaje de cara a las nuevas posibilidades de programar.
Los operadores
Las variables se manipulan muchas veces utilizando operaciones con ellos. Los datos se suman,
se restan, multiplican, etc. y a veces se realizan operaciones más complejas.
Operadores aritméticos
Cabe destacar que el operador % es de uso exclusivo entre enteros. Por ejemplo:7%3 devuelve
1 ya que el resto de dividir 7 entre 3 es 1. Al valor obtenido lo denomina módulo (en otros
lenguajes en vez del símbolo % se usa la palabra clave mod) y a este operador a veces se le
denomina “operador módulo”. Las operaciones con operadores siguen un orden de prelación o
de precedencia que determinan el orden con el que se ejecutan. Si existen expresiones con
varios operadores del mismo nivel, la operación se ejecuta de izquierda a derecha. Para evitar
resultados no deseados, en casos donde pueda existir duda se recomienda el uso de paréntesis
para dejar claro con qué orden deben ejecutarse las operaciones. Por ejemplo, la expresión
3 ∗ 2 /7 + 2
Podría generar cierta incertidumbre respecto del orden en el que se ejecutarán las operaciones.
Al agregar paréntesis, como, por ejemplo:
3 ∗ ((2/7) + 2)
No quedan dudas del orden en que se ejecutarán las expresiones. ¿La primera expresión es
equivalente a la segunda?
Operadores lógicos
Los conectivos lógicos (AND, OR y NOT), sirven para evaluar condiciones complejas. NOT sirve
para negar una condición. Ejemplo:
El operador && (AND) sirve para evaluar dos expresiones de modo que, si ambas son ciertas, el
resultado será true sino el resultado será false. Ejemplo:
El operador || (OR) sirve también para evaluar dos expresiones. El resultado será true si al
menos una de las expresiones es true. Ejemplo:
En un caso como:
Operadores de asignación
Permiten asignar valores a una variable. El operador fundamental es “=”. Por ejemplo:
Sin embargo, Java dispone de las siguientes expresiones de asignación más complejas:
En el caso del incremento sufijo (x++ en el ejemplo) primero se asigna el valor de x a z, y luego
se incrementa en uno x.
En el caso del incremento prefijo (++y en el ejemplo) primero se incrementa en uno y, y luego
se asigna este valor a z.
Operador ternario
Este operador (conocido como if de una línea) permite devolver un valor u otro según el valor
de la expresión analizada. Su sintaxis es la siguiente:
Por ejemplo:
Las constantes
Una constante es una “variable” de solo lectura. Dicho de otro modo, más correcto, es un valor
que no puede variar (por lo tanto, no es una variable en sí). La forma de declarar constantes es
similar a la utilizada para definir variables, sólo que hay que anteponer la palabra reservada
final (que es la que indica que estamos declarando una constante). Como no se podrá variar
su valor, es requerido inicializar la constante al momento de definirla. Observe el siguiente
ejemplo de definición de una constante:
Es una buena práctica comúnmente aceptada el asignar nombres en mayúscula sostenida para
las constantes a fin de diferenciarlas luego en el código del programa. Si el nombre de la
constante está formado por varias palabras se las separa usando el carácter “_”.
Estructuras de control
Estructuras condicionales
Está conformada esencialmente por dos tipos de estructuras: bifurcación y selección múltiple.
Su sintaxis es
Es necesario que condición sea una variable o expresión booleana. Si sólo existe una
instrucción en el bloque, las llaves no son necesarias. No es necesario que exista un bloque else,
como en el siguiente ejemplo:
Cada cláusula else corresponde al último if inmediato anterior que se haya ejecutado, es por eso
por lo que se debe tener especial consideración de encerrar correctamente entre llaves los
bloques para determinar exactamente a qué cláusula corresponde. En este caso, es de especial
Su sintaxis es la siguiente:
La expresión ha de ser una variable de tipo int o una expresión que devuelva un valor entero.
Cuando se encuentra coincidencia con un case se ejecutan las instrucciones a él asociadas
hasta encontrar el primer break. Si no se encuentra ninguna coincidencia se ejecutan las
instrucciones del bloque default, la cual es opcional. El break no es exigido en la sintaxis y
entonces si no se pone, el código se ejecuta atravesando todos los cases hasta que encuentra
uno.
atención a los bucles infinitos, hecho que ocurre cuando la condición de finalización del bucle
(expresión booleana) no se llega a cumplir nunca.
Bucle while
El bucle while se utiliza para repetir un conjunto de sentencias siempre que se cumpla una
determinada condición. Es importante reseñar que la condición se comprueba al comienzo del
bucle, por lo que se podría dar el caso de que dicho bucle no se ejecutase nunca. La sintaxis es
la siguiente
Las sentencias se ejecutan una y otra vez mientras expresion sea verdadera
Ejemplo: Visualice mediante una estructura while los 10 primeros números naturales.
Observe que se inicializa la variable i en 1. Mientras i sea menor que el número 11, se visualiza
su valor en consola y luego se incrementa en uno su valor.
Bucle do-while
El bucle do-while funciona de la misma manera que el bucle while, con la salvedad de que
expresion se evalúa al final de la iteración. Las sentencias que encierran el bucle do-while, por
tanto, se ejecutan como mínimo una vez. La sintaxis es la siguiente:
El siguiente ejemplo es el equivalente do-while al ejemplo anterior que muestra los valores del
1 al 10.
Bucle for
Justo al principio se ejecuta expresion1, normalmente se usa para inicializar una variable. El
bucle se repite mientras se cumple expresion2 y en cada iteración del bucle se ejecuta
expresion3, que suele ser el incremento o decremento de una variable. Con un ejemplo se verá
mucho más claro:
En este ejemplo, int i = 1 se ejecuta solo una vez, antes que cualquier otra cosa dentro del
bucle; como puede observar, esta expresión se utiliza para inicializar la variable i en 1. Mientras
se cumpla la condición i < 11 el contenido del bucle, o sea, System.out.println(i); se va a
ejecutar. En cada iteración del bucle, i++ incrementa la variable i en 1. El resultado del ejemplo
es la impresión en pantalla de los números 1 al 10. Si sigue mentalmente el flujo del programa,
podría experimentar inicializando la variable i con otros valores, cambiando la condición con >
o <= y observar lo que sucede. Pruebe también cambiar el incremento de la variable i, por
ejemplo, con i = i + 2 y reflexione los resultados.