Está en la página 1de 13

Programación en

Java/Características del
lenguaje
Es un lenguaje sencillo de aprender. Su sintaxis es la de
C++ “simplificada”. Los creadores de Java partieron de la sintaxis de C++ y trataron de
eliminar de este todo lo que resultase complicado o fuente de errores en este lenguaje.

Java es un lenguaje orientado a objetos, aunque no de los denominados puros; en Java


todos los tipos, a excepción de los tipos fundamentales de variables (int, char, long...)
son clases. Sin embargo, en los lenguajes orientados a objetos puros incluso estos tipos
fundamentales son clases, por ejemplo en Smalltalk.

El código generado por el compilador Java es independiente de la arquitectura:


podría ejecutarse en un entorno UNIX, Mac o Windows. El motivo de esto es que el que
realmente ejecuta el código generado por el compilador no es el procesador del
ordenador directamente, sino que este se ejecuta mediante una máquina virtual. Esto
permite que los Applets de una web pueda ejecutarlos cualquier máquina que se conecte
a ella independientemente de qué sistema operativo emplee (siempre y cuando el
ordenador en cuestión tenga instalada una máquina virtual de Java).

Características

 Lenguaje totalmente orientado a Objetos. Todos los conceptos en los que se apoya
esta técnica, encapsulación, herencia, polimorfismo, etc., están presentes en Java.
 Disponibilidad de un amplio conjunto de librerías. Como ya se mencionó
anteriormente, Java es algo más que un lenguaje. La programación de aplicaciones con
Java se basa no solo en el empleo del juego de instrucciones que componen el
lenguaje, sino, fundamentalmente, en la posibilidad de utilizar el amplísimo conjunto
de clases que Sun pone a disposición del programador y con las cuales es posible
realizar prácticamente cualquier tipo de aplicación.
 Lenguaje simple. Java posee una curva de aprendizaje muy rápida. Resulta
relativamente sencillo escribir applets interesantes desde el principio. Todos aquellos
familiarizados con C++ encontrarán que Java es más sencillo, ya que se han eliminado
ciertas características, como los punteros. Debido a su semejanza con C y C++, y dado
que la mayoría de la gente los conoce aunque sea de forma elemental, resulta muy
fácil aprender Java. Los programadores experimentados en C++ pueden migrar muy
rápidamente a Java y ser productivos en poco tiempo.
 Distribuido Java proporciona una colección de clases para su uso en aplicaciones de
red, que permiten abrir sockets y establecer y aceptar conexiones con servidores o
clientes remotos, facilitando así la creación de aplicaciones distribuidas.
 Interpretado y compilado a la vez Java es compilado, en la medida en que su código
fuente se transforma en una especie de código máquina, los bytecodes, semejantes a
las instrucciones de ensamblador. Por otra parte, es interpretado, ya que los
bytecodes se pueden ejecutar directamente sobre cualquier máquina a la cual se
hayan portado el intérprete y el sistema de ejecución en tiempo real (run-time).
 Robusto Java fue diseñado para crear software altamente fiable. Para ello proporciona
numerosas comprobaciones en compilación y en tiempo de ejecución. Sus
características de memoria liberan a los programadores de una familia entera de
errores (la aritmética de punteros), ya que se ha prescindido por completo los
punteros, y la recolección de basura elimina la necesidad de liberación explícita de
memoria.
 Seguro (?) Dada la naturaleza distribuida de Java, donde las applets se bajan desde
cualquier punto de la Red, la seguridad se impuso como una necesidad de vital
importancia. A nadie le gustaría ejecutar en su ordenador programas con acceso total
a su sistema, procedentes de fuentes desconocidas. Así que se implementaron
barreras de seguridad en el lenguaje y en el sistema de ejecución en tiempo real.
 Indiferente a la arquitectura Java está diseñado para soportar aplicaciones que serán
ejecutadas en los más variados entornos de red, desde Unix a Windows Nt, pasando
por Mac y estaciones de trabajo, sobre arquitecturas distintas y con sistemas
operativos diversos. Para acomodar requisitos de ejecución tan diversos o variopintos,
el compilador de Java genera bytecodes: un formato intermedio indiferente a la
arquitectura diseñada para transportar el código eficientemente a múltiples
plataformas hardware y software. El resto de problemas los soluciona el intérprete de
Java.
 Portable La indiferencia a la arquitectura representa sólo una parte de su portabilidad.
Además, Java especifica los tamaños de sus tipos de datos básicos y el
comportamiento de sus operadores aritméticos, de manera que los programas son
iguales en todas las plataformas. Estas dos últimas características se conocen como la
Máquina Virtual Java (JVM).
 Alto rendimiento
 Multihebra Hoy en día ya se ven como terriblemente limitadas las aplicaciones que
sólo pueden ejecutar una acción a la vez. Java soporta sincronización de múltiples hilos
de ejecución (multithreading) a nivel de lenguaje, especialmente útiles en la creación
de aplicaciones de red distribuidas. Así, mientras un hilo se encarga de la
comunicación, otro puede interactuar con el usuario mientras otro presenta una
animación en pantalla y otro realiza cálculos.
 Dinámico El lenguaje Java y su sistema de ejecución en tiempo real son dinámicos en
la fase de enlazado. Las clases sólo se enlazan a medida que son necesitadas. Se
pueden enlazar nuevos módulos de código bajo demanda, procedente de fuentes muy
variadas, incluso desde la Red.
 Produce applets Java puede ser usado para crear dos tipos de programas: aplicaciones
independientes y applets. Las aplicaciones independientes se comportan como
cualquier otro programa escrito en cualquier lenguaje, como por ejemplo el navegador
de Web HotJava, escrito íntegramente en Java. Por su parte, las applets son pequeños
programas que aparecen embebidos en las páginas Web, como aparecen los gráficos o
el texto, pero con la capacidad de ejecutar acciones muy complejas, como animar
imágenes, establecer conexiones de red, presentar menús y cuadros de diálogo para
luego emprender acciones, etc.
Tipo de variable

Cada variable debe tener un tipo de dato predefinido. Esto determina el rango de valores
que puede almacenar y que operaciones se pueden realizar. Por ejemplo una variable de
tipo entero puede almacenar números sin decimales y puede realizarse operaciones
aritméticas, pero no puede contener palabras.

Existen dos categorías de variables: las de tipo primitivo o las referenciadas. Una
variable de tipo primitivo accede al valor asignado directamente. Las referenciadas se
accede a través de un puntero, es decir que no almacenan un valor sino una dirección de
memoria. Estas últimas son utilizadas por las matrices , las clases e interfaces.

Tipos de datos primitivos

Tipo Tamaño y formato Rango

  enteros  

byte 8 bits - complemento a 2

short 16 bits - complemento a 2 -

int 32 bits - complemento a 2

long 64 bits - complemento a 2

  números reales  

float 32 bits - IEEE 754  

double 64 bits - IEEE 754  

  otros  

char 16 bits - caracteres UNICODE '\u0000' al '\uffff'

boolean 1 bit true o false


En otros lenguajes de programación, el formato o el tamaño de los tipos primitivos
dependen del microprocesador o del sistema operativo que se están ejecutando. En
cambio, Java pretende ser independiente de la plataforma, y mantiene los formatos sin
cambios. Para los caracteres alfanuméricos utiliza la codificación UNICODE de 16 bits
para permitir la inclusión de varios alfabetos.

ARRAYS (vectores y matrices)

En java a diferencia del lenguaje C, existe un tipo de variable “especial”, el Array. Este
tipo de variables no es más que un conjunto secuencial de memoria a las que se accede a
través de un índice de posición.

Los arreglos en Java son objetos, por lo que cuentan con propiedades y métodos para
manipularlos. Se pueden declarar arreglos de tipos de datos primitivos y de objetos.

Más abajo tienes la sintaxis básica de declaración de arrays.

Sintaxis:

 tipodedato nombre [] [= new tipodedato[capacidad]] o


 tipodedato[] nombre [= new tipodedato[capacidad]]

Como puedes observar puedes inicializar un array al momento de declararlo o postergar


esta operación para cuando sea necesario.

Para inicializar un array existen 2 maneras:

 int[] arreglo=new int[4] o


 int[] arreglo={100,200,302,400}

Como podrás concluir la primera declaras el array nada más diciéndole la cantidad de
memoria secuencial que se debe reservar, en el segundo ejemplo se inicializa el array
dándole los valores que va a contener (obviamente la cantidad de memoria secuencial
reservada sera igual a la cantidad de elementos insertados).

Al momento de inicializar un arreglo de la manera :

 int[] arreglo=new int[4]

cada posición del arreglo sera inicializada con el valor por defecto del tipo de variable.
Por ejemplo si el arreglo si el arreglo es de tipo boolean, todas las posiciones del arreglo
serán inicializadas con el valor false (ya que este es valor por defecto de este tipo de
dato), por el contrario si el arreglo fuese de un tipo no primitivo, el valor que contendrá
cada casilla sera null.

A continuación tienes una lista de los valores por defecto de cada tipo de dato

Tipo de Dato-->Valor
byte-->0
short-->0
int-->0
long-->0
float-->0.0
double-->0.0
char-->/u0000
boolean-->false
Object (Cualquier tipo de Objeto)-->null

Para obtener el tamaño de un array de manera dinámica se utiliza la propiedad .length,


esta propiedad es común para todos los array . También es importante saber que los
arreglos se empiezan a enumerar desde el numero (0) cero por tanto para acceder al
valor almacenado en la última posición deberás colocar el tamaño del arreglo menos 1
unidad.

Al momento de tratar de acceder a una posición fuera del rango del arreglo se lanzara un
exception de tipo java.lang.ArrayIndexOutOfBoundsException (esta exception es
una exception no chequeada es por eso que no es necesario colocar un bloque try/catch
en el código)

Pasaremos con un ejemplo:

public class Arrays01 {


public static void main(String args[]) {
int ita_nro[] = new int[4];
int it_cont;
for (it_cont = 0;it_cont < 4; it_cont ++){
ita_nro[it_cont] = it_cont * 2;
System.out.println(ita_nro[it_cont]);
}
}
}

EJEMPLO DE UNA CLASE

//Inicialización de la clase

public class Persona{

// Inicio de los atributos de la clase

String Nombre; int Edad;


//Inicio de la declaración de los métodos de la clase

public int MostrarEdad (){

System.out.println("La edad es: "+Edad); return Edad;

USO DE OBJETOS

Un objeto es la instancia de una clase. Por ejemplo, si tenemos una clase perro definida
de la siguiente manera:

public class Perro


{
private String color; // a traves de esta variable
almacenaremos el color del perro
private int numPatas; // a traves de esta otra almacenaremos el
numero de patas

public Perro(String col, int numP) // cabecera del constructor


de la funcion
{
color=col; // ponemos los valores que nos pasan por
parametro a las variables del objeto
numPatas=numP;
}
}

Una instancia de la clase sería un perro en particular:

Perro snoopy = new Perro("blanco", 4);

En este caso estamos definiendo una nueva instancia de la clase "Perro" que llamamos
snoopy, que definimos con pelo blanco y 4 patas (si, según esto podríamos crear perros
o aberraciones de la naturaleza con otro número, XD).

SENTENCIA IF - else

Las buenas prácticas en defensa de un código mantenible han dictaminado que


utilicemos las llaves en todo momento, aún en el caso que utilicemos una sola sentencia.

if (condición) {
sentencia;
} else {
sentencia;
}
Los operadores lógicos nos permiten simplificar la estructura. Sin ellos nos veríamos en
la necesidad de anidar las sentencias. Veamos que ocurre si en elejemplo anterior
descartamos el AND y el OR.

if ( x % 4 == 0 ) {
if ( x % 100 == 0 ) {
if ( x % 400 == 0 ) {
System.out.println("Es bisiesto");
} else {
System.out.println("No es bisiesto");
}
} else {
System.out.println("Es bisiesto");
}
} else {
System.out.println("No es bisiesto");
}

Parece complicado, pero nos demuestra muchas cosas. En primer lugar observamos que
se pueden anidar las sentencias if-else. Cada resultado de una condición puede caer en
una nueva comprobación para formar una estructura compleja de selección.

También vemos que hay cierta relación entre conectores lógicos y la estructura.

Conjunción
if (condición1 && condición2){ if ( condición1 ) {
sentecia1; if ( condición2 ) {
} else { sentencia1;
sentencia2; } else {
} sentencia2;
}
} else {
sentencia2;
}

Disyunción  
if ( condición1 || condición2 ) { if ( condición1 ){
sentencia1; sentencia1;
} else { } else {
sentencia2; if ( condición2 ) {
} sentencia1;
} else {
sentencia2;
}
}

Negación  
if ( ! condición1) { if ( condición1) {
sentencia1; sentencia2;
} else { } else {
sentencia2; sentencia1;
} }
USO DEL SWITCH

public class MiniCalculadora{


public static void main(String args[]){
int a = 1;
int b = 1;
char op = '/';
System.out.print("El resultado es : ");
switch ( op ) {
case '+':
System.out.println( a + b );
break;
case '-':
System.out.println( a - b );
break;
case '*':
System.out.println( a * b );
break;
case '/':
System.out.println( a / b );
break;
default:
System.out.println("error" );
break;
} }}
SENTENCIA FOR

Imprimiremos una tabla de multiplicar hasta el factor noveno. Si no utilizamos ninguna


estructura de interacción, deberíamos imprimir nueve líneas de código secuencial.

System.out.println("3 x 1 = 3");
System.out.println("3 x 2 = 6");
System.out.println("3 x 3 = 9");
System.out.println("3 x 4 = 12");
System.out.println("3 x 5 = 15");
System.out.println("3 x 6 = 18");
System.out.println("3 x 7 = 21");
System.out.println("3 x 8 = 24");
System.out.println("3 x 9 = 27");

Pero ya conocemos las estructuras que nos ahorran el esfuerzo de escribir tanto código.
Utilizaremos una sentencia que ya conocemos: el while

int factor = 1;
while ( factor <= 9 ) {
System.out.println("3 x " + factor + " = " + 3*factor );
factor++;
}

Utilizamos la variable factor para contar la cantidad de líneas que imprimimos.


Primeramente la inicializamos en uno. Cuando se ejecuta la interacción se controla que
no supere su valor de 9. Si el valor es menor o igual que nueve, imprime una línea de la
tabla e incrementa a uno el valor de factor. Cualquier caso de interacción que se
complete en una cantidad prefijada de ciclos, necesitamos una variable de control. Si
utilizamos la sentencia while, esta variable se debe definir e inicializar antes del bucle y
contar con una instrucción que modifique su valor dentro del bucle.

Veremos como este código cambia ligeramente si en lugar de while presentamos una
nueva sentencia denominada for

for ( int factor = 1; factor <= 9; factor ++ ) {


System.out.println("3 x " + factor + " = " + 3*factor );
}

la sentencia for me permite repetir un ciclo n veces, en donde se debe determinar el


valor inicial y cuantas veces se repetira.

sintaxis

for({valor inicial};{condición de termino};{factor de incremento del


valor inicial}){
//acá va lo que se repetirá n veces de acuerdo a la condición de
termino
}

Bucle infinito: no hay control, entonces no se detiene

for ( ;;){}

Operador coma :

for ( int k=1, j=10 ;k < j ;k++ ,j-- ){


System.out.println(k + " " + j);
}

for mejorado

Supongamos que tenemos un arreglo de enteros que deseamos presentar en pantalla,


usando la orden for tradicional, el código, podría quedar así:

int[] laiEnteros = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


for (int i = 0; i < 10; i ++)
System.out.println (laiEnteros[i]);

Java ofrece una funcionalidad extra para la orden for, mediante la que se puede
simplificar notablemente el codigo anterior, quedando así:

int[] laiEnteros = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};


for (int liElemento : laiEnteros)
System.out.println (liElemento);

En este caso, liElemento toma el valor de cada uno de los elementos de laiEnteros,
permitiendo una navegación más simple, puesto que se evitan posibles errores derivados
del uso de los arreglos en forma directa. También se puede usar esta forma, para
estructuras más complejas como objetos de la clase Collection
public void Presenta (Collection <Integer> poConjunto){
for (Iterator <Integer> loElemento : poConjunto)
System.out.println (loElemento)
}

SENTENCIA DO-WHILE

La sentencia de iteración do-while es de tipo posprueba. Primero realiza las acciones


luego pregunta. La sintaxis es la siguiente:

do sentencia while ( condición );

Observamos que es como un while pero al revés. Primeramente se ejecuta la sentencia y


luego evalúa la condición. Si la expresión de la condición es verdadera vuelve a dar un
ciclo. De lo contrario, termina. Esto nos garantiza que la sentencia se ejecute al menos
una vez.

do System.out.println("Lo veras una vez");


while ( false );

Resulta útil para los casos en donde tendremos que realizar ciertas acciones antes de
verificar una condición.

Realicemos un programa que cuente la cantidad de dígitos que posee un número. Para
ello tendremos que dividir por diez el número que nos han dado, hasta que el resultado
se vuelva cero. Entonces recurrimos al while para realice los ciclos necesarios.

public class CuentaDigitos{


public static void main(String args[]){
int número = 4557888;
int dígitos = 0;
while ( número > 0 ) {
número /=10;
dígitos++;
}
System.out.println(dígitos);
}
}

¿Qué ocurre si el número que nos dan es el cero? El resultado nos dará cero.
Obviamente es erróneo, debería devolver un dígito. Pero no entra en el ciclo debido a
que de entrada no satisface la condición. Podríamos implementar una solución "ad hoc".

número /=10;
dígitos++;
while ( número > 0 ) {
número /=10;
dígitos++;
}

Realizamos primeramente las operaciones y luego entramos en el bucle si se verifica la


condición. Pero no hace falta mirar mucho para darnos cuenta que es una solución poco
elegante. En realidad quedará mejor con la sentencia do-while
public class CuentaDigitos{
public static void main(String args[]){
int número = 4557888;
int dígitos = 0;
do {
número /=10;
dígitos++;
}
while ( número > 0 );
System.out.println(dígitos);
}
}

SENTENCIA WHILE

La sentencia while es la más sencilla de las estructuras de iteración. La iteración


continuará hasta que su condición sea falsa.

while ( condición ) sentencia ;

La condición tiene que tomar un valor booleano (verdadero o falso). Si este valor es
verdadero, se ejecutará la sentencia. Concluida esta acción se vuelve a evaluar la
condición. Proseguirán los ciclos hasta que la condición no cambie a falso.

Esta es una estructura de iteración preprueba, es decir primero se evalúa la condición


antes de realizar cualquier acción. Si de entrada la condición es falsa nunca ejecutará el
conjunto de sentencias.

int n = 0;
while ( n > 0 ) System.out.println("Esto nunca lo verás");

Dentro del conjunto de sentencia que controla, debe existir alguna que cambie el valor
de la condición que se está evaluando.

boolean prueba = true;


while ( prueba ) {
System.out.println("Esto lo verás una vez");
prueba = false;
}

Entraríamos en un ciclo infinito si nunca se modifica la condición y permanece


verdadera.

boolean prueba = true;


while ( prueba ) {
System.out.println("Esto lo verás muchas veces");
}

Generalmente esta estructura se utiliza en situaciones en donde desconocemos la


cantidad de ciclos que se deben ejecutar para producir un resultado. Mostraremos como
se utiliza en estas circunstancias con el ejemplo de pase a binario, mostrado en el
capítulo anterior.
Teníamos que transformar un número decimal a binario. El programa en java nos queda
de esta manera:

public class Dec2Bin{


public static void main(String args[]){
int decimal = 252222;
String binario = "";
while ( decimal > 0 ) {
binario = decimal % 2 + binario;
decimal /= 2;
}
System.out.println(binario);
}
}

Como no sabemos de antemano cuantas vueltas debe dar, simplemente esperamos que
el resultado de las divisiones sucesivas sea igual a cero.

También se pueden realizar ciclos con while en donde ya conocemos, antes de entrar en
la estructura, cuantas vueltas debe dar para terminar. Para esto nos auxiliamos con un
contador de vueltas. Previamente tiene que inicializarse antes de ingresar al ciclo. Luego
en cada vuelta se modificara según la lógica del algoritmo.

Realicemos el programa que despliegue por pantalla cinco líneas de caracteres.

public class Cuadrado{


public static void main(String args[]){
int contador = 1;
while ( contador <= 5 ) {
System.out.println("*****");
contador++;
}
}
}

En este algoritmo, inicializamos el contador a 1 y luego en cada ciclo se incrementa. La


condición de corte tiene como objetivo no permitir más vueltas si el contador superó el
valor 5.

Para tener varias veces el asterisco sin necesidad de imprimirlo asi "*****", utilizamos
otro ciclo while y otra variable que inicializaremos dentro del ciclo para que se cumpla
la cual llamaremos "contador2", obtendremos el mismo resultado que el anterior, el
codigo quedaria asi:

public class Cuadrado {

public static void main (String args [])


{
int contador = 1;
while (contador <= 5)
{
int contador2 = 1;
while (contador2 <= 5)
{
System.out.print ("*");
contador2++;
}
System.out.println ();
contador++; } } }

También podría gustarte