Introducción a la Programación

3 Identificadores, Operadores y Expresiones

En este capítulo vamos a analizar los elmentos esenciales de Java: sus tipos de datos, los operadores y las expresiones.

3.1 Juego de Caracteres

Java utiliza un juego de caracteres de 16 bits (216=65536 posibles caracteres). Lo que significa que puede representar muchos más caracteres que los 256 posibles del código ASCII, usual en la mayoría de los lenguajes de programación utilizados. Esto significa que se pueden utilizar en los programas Java códigos pertenecientes a diferentes lenguajes. Para facilitar la correspondencia entre los códigos ASCII y los Unicode, los entornos Java actuales leen programas escritos en ASCII estándar o ISO Latin 1.

Como los editores no soportan caracteres Unicode, Java reconoce la sentencia de escape \uddd para codificar caracteres Unicode, en la que cada d es un dígito hexadecimal (por ejemplo, el carácter \u2603 es un muñeco de nieve).

3.2 Comentarios

Es fundamental ir acompañando de comentarios el código que se escribe, lo que facilita su comprensión y la detección de errores, aunque haya pasado tiempo desde que fue escrito, o fuese otra persona la que lo escribió. Evidentemente, los comentarios no han de ser considerados por el compilador Java, y están dirigidos exclusivamente para que los programadores entendamos el código. Un programa sin comentarios funciona perfectamente, pero será más difícil, si no imposible de modificar que otro que sí los tenga. Además, conviene adoptar el buen hábito de comentar el código desde el principio, para que comentar y programar sea una misma cosa.

Los tres tipos de comentarios de Java son:

Java no permite comentarios anidados, por lo que el siguiente trozo de código no compilará:

/* esto es un comentario
/* a=3; */
fin del comentario */

Ya que el primer grupo /* se empareja con el primer grupo */. Para evitar eso es mejor utilizar la doble barra cuando se quiere comentar una línea dentro de un comentario.

/* esto es un comentario
// a=3;
fin del comentario */

Resulta interesante analizar el siguiente ejemplo de código:

/** una de nuestas clases de ejemplo */
class HolaMundo2{
   /** el metodo main de la clase HolaMundo */
   public static void main(String[] args) {
      //String mensaje="Hola otra vez mundo";
      String mensaje="Saludos";
      System.out.println(mensaje);
   }
} // fin de la clase HolaMundo2

3.3 Sentencias

Una sentencia es una línea de código Java. No existe correspondencia entre uno a uno entre las líneas de código y las líneas de texto en un fichero de código fuente. Java utiliza el punto y coma para indicar el final de una sentencia. La línea

a = b + c + d + e + f;

es equivalente a

a = b + c + 
d + e + f;

Bloques de Código

Las sentencias se pueden agrupar en bloques para que una sola pueda controlar de manera sencilla la ejecución de muchas otras. Los bloques de código Java están delimitados por llaves '{','}'. Los bloques de código se pueden anidar dentro de otros bloques. Estructura de los Ficheros Fuente: Paquetes

Los ficheros de código fuente en Java pueden contener sólo tres tipos de sentencias fuera de bloques de código:

Estos tres tipos de sentencias reseñadas no son obligatorias en todos los programas, pero si aparecen deben hacerlo en el orden especificado:package, import y class.

3.4 Tokens

Los tokens de un lenguaje son sus palabras básicas. Un analizador sintáctico descompone el código fuente en tokens y a continuación trata de averiguar qué sentencias, identificadores y otros elementos componen el código.

En Java, los espacios en blanco (espacios, tabuladores, saltos de línea y saltos de página) no tienen significado; sirven sólo para separar tokens o como contenido de literales de carácter o de cadena de caracteres.

El espacio en blanco es necesario para separar tokens que de otro modo constituirían un token único. Así, por ejemplo, en la sentencia

return 0;

no se puede eliminar el espacio en blanco pues se crearía la sentencia no válida

return0;

El programador debe usar espacios en blanco extra cuando esto facilite la legibilidad del código, tal y como ocurre en la identación:

{
   sentencia 1 
   sentencia 2 {
      sentencia 2.1
      sentencia 2.2 {
         sentencia 2.2.1
         sentencia 2.2.2
      }
   }
   sentencia 3
}

3.5 Identificadores

Un identificador es un nombre que se le da a una variable, clase o constante. Los identificadores deben comenzar por carácter alfabético (incluidos el carácter subrayado '_' y el dólar '$'), seguido por cualquier carácter alfabético o numérico (esto considerándolos como caracteres unicode).

Cualquier diferencia en los caracteres de dos identificadores ya les hace diferentes y únicos. Uno de los recursos para diferenciar dos indentificadores es el uso de las mayúsculas y las minúsculas; y aunque no existe ninguna regla, existe una forma de utilizarlas dependiendo del tipo de identificador que se esté construyendo:

Tipo de Identificador Convenio Ejemplo
Identificadores de clases Cada palabra dentro del identificador comienza por mayúscula HolaMundo, Automóviles
Identificadores de métodos Cada palabra dentro del identificador comienza por mayúscula, excepto la primera insertarLibro, main
Identificadores de variables Cada palabra dentro del identificador comienza por mayúscula, excepto la primera numeroVeces, mensaje
Identificadores de constantes Cada palabra dentro del identificador se escribe en mayúsculas, y se separan por el símbolo subrayado MAXIMO_TOTAL

3.5.1 Palabras Reservadas Java

Las palabras clave Java no se pueden usar como identificadores y son las que aparecen en la siguiente lista: abstract, boolean, break, byte, case, catch, char, class, const, continue, default, do, double, else, extends, final, finally, float, for, goto, if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public, return, short, static, super, switch, syncronized, this, throw, throws, transient, try, void, volatile, while. Aunque null, true y false no son palabras clave, se les aplican las mismas restricciones.

3.6 Variables y Tipos de Datos

Las variables son los sustantivos de los lenguajes de programación. En una primera aproximación se puede decir que son almacenes de información. Esta información puede variar a lo largo del tiempo, por lo que se justifica el nombre de variable para estos almacenes. Cada una de las variables tiene un nombre o identificador que la diferencia del resto y sirve para invocar a su contenido, (invariable en el tiempo), y sirve para almacenar un tipo de dato concreto.

3.6.1 Tipos Primitivos

Algunas de las palabras reservadas son nombres de tipos de datos Java:

Tipo Descripción
boolean Valor lógico true o false
char Carácter Unicode 1.1.5, 16 bits.
byte Entero en complemento a dos con signo, 8 bits.
short Entero en complemento a dos con signo, 16 bits.
int Entero en complemento a dos con signo, 32 bits.
long Entero en complemento a dos con signo, 64 bits.
float Número en punto flotante IEEE 754-1985, 32 bits.
double Número en punto flotante IEEE 754-1985, 64 bits.

3.6.2 Literales

En Java, cada uno de los tipos de datos tiene literales, que es como se escriben los valores constantes de cada tipo. En los apartados siguientes se describe cómo se especifican constantes literales para cada tipo.

Literales Booleanos

Los literales booleanos son true y false.

Literales Enteros

Las constantes enteras son cadenas de dígitos octales, decimales o hexadecimales. El comienzo de la constante declara la base del número:

Las constantes enteras con long si terminan en L o en l, (29L). En otro caso se supone que son de tipo int. Si un literal de tipo int se asigna a un short o a un byte y su valor está dentro del rango válido para ese tipo, el literal entero se trata como si fuera un short o un byte.

Literales en Punto Flotante

Los números en punto flotante se expresan como números decimales con punto decimal opcional, seguidos opcionalmente por un exponente. Deben contener como mínimo un dígito: 18., 1.8e1, .18E2

El numero puede ir seguido por f o F para denotar una constante de simple precisión, o por d o D para las constantes de doble precisión: 1.8F , 1.8D. Las constantes de tipo punto flotante son de doble precisión a menos que se diga lo contrario.

El cero puede ser positivo, +0.0, o negativo, -0.0. Ambos son iguales a efectos de comparación, aunque producen resultados distintos cuando se utilizan en expresiones (1.0d/0.0d es positivo, mientras que 1.0d/-0.0d es negativo).

Una constante double no se puede asignar diretamente a una variable float aunque esté en el rango permitido. Se debe usar una constante float o convertir la double a float.

Literales Carácter

Los literales de carácter aparecen entre comillas simples, como 'a'. Ciertos caracteres especiales se pueden representar utilizando secuencias de escape:

Literales Cadenas de Caracteres

Los literales de cadenas de caracteres son secuencias de caracteres entre comillas dobles: "Hola mundo". Todas las secuencias de escape para los literales tipo caracter son válidas para las cadenas de caracteres. Un literal de cadena de caracteres referencia un objeto de tipo String, aunque esto ya lo explicaremos más adelante.

Literales Referencia

La única referencia literal de objeto es null. Se puede usar en cualquier lugar donde se espere una referencia. null representa un objeto no válido o no creado.

3.6.3 Variables

Antes de usar una variable debe ser declarada. La declaración de una variable especifica el tipo de datos, el nombre de la variable y, opcionalmente, el valor por defecto de la variable. Más adelante se explicará cómo limitar el acceso a una variable en su declaración. Una declaración general de variable es del tipo:

tipo_de_dato identificador [= valor_por_defecto] {, identificador [= valor_por_defecto] }*

La parte del tipo de una declaración dice qué valores va a admitir esa variable y el comportamiento de la misma. Los identificadores son tan sólo símbolos, los nombres de las variables que se están definiendo.

No hay diferencia entre declarar las variables en una sola declaración o declararlas en múltiples declaraciones del mismo tipo. Por ejemplo

int i=1;
int j=2;
int k;
k=3;

es equivalente a

int i=1, j=2, k=3;

Las declaraciones de variables se pueden poner en cualquier lugar del código, siempre y cuando precedan al primer uso de la variable. Sin embargo, es práctica común situar las declaraciones al principio de cada bloque de código.

Variables de Tipo Booleano

Las variables tipo booleano contienen los valores verdad o falso. Las variables de tipo booleano sin inicializar se inicializan a false.

Variables de Tipo Carácter

El tipo de datos carácter, char, contiene un solo carácter. Cada carácter es un número o código de ccarácter que se refiere al juego de caracteres Unicode. Y esto es así porque los diseñadores de Java tuvieron en cuenta la internacionalización y la escalabilidad. Las variables de tipo carácter se inicializan a '\u0000'.

Variables de Tipo Numérico

Java posee seis tipos de datos numéricos que difieren en el tamaño y en la precisión de los números que puede contener. Generalmente, cuando se escoge un tipo de datos para una variable, se deberá usar el tipo de dato más pequeño que contenga el mayor número con el que se va a trabajar, ahora o en un futuro previsible. Esto ahorra memoria, al tiempo que proporciona espacio para futuras expansiones que necesite el código.

La VM de Java inicializa cada variable numérica a cero antes de su uso (0, 0.0f o 0.0d, dependiendo si son enteras o de punto flotante de simple o doble precisión). Esto constrasta con la mayoría de los lenguajes de programación en que las variables no inicializadas contienen valores aleatorios.

Variables de Tipo String

Un String (cadena) es una secuencia de caracteres. El tipo de datos String es en realidad una clase del núcleo API (java.lang.String), más que un tipo integrado, pero se utiliza tan frecuentemente que es apropiado introducirlo aquí.

Los Strings pueden ser tan largos como se desee; no se ha definido una longitud máxima en la especificación de Java. Sin embargo, la mayoría de las implementaciones la limitarán probablemente en torno a los dos mil millones de caracteres, (2GB), lo que supone capacidad más que suficiente para casi cualquier aplicación.

Los Strings son de sólo lectura, es decir, no se puede cambiar el contenido de un String, aunque se puede redefinir una variable de tipo String (Java proporciona la clase StringBuffer para las cadenas de caracteres modificables). Así, la variable String mensaje definida inicialmente como:

String mensaje = "Hola mundo";

no se puede variar su contenido. Aunque si que se puede conseguir que la variable mensaje apunte a otro objeto String:

mensaje = mensaje + "!!";

3.6.4 Variables de Array

En esta sección vamos a presentar un tipo de variable muy utilizado en programación llamado array. Mostraremos las operaciones básicas con arrays: su declaración, la creación, el acceso a los elementos y la cópia de arrays.

Declaración de un Array

Un array es un grupo de variables del mismo tipo a las que podemos referirnos mediante un nombre común. El tipo puede ser o bien uno primitivo como int, o de tipo objeto como String.

Si quisieramos almacenar la temperatura máxima de los días de la semana de podrían utilizar 7 variables enteras de la siguiente manera:

int maxLunes, maxMartes, maxMiercoles, maxJueves, maxViernes,
maxSabado, maxDomingo;

Pero, dado que se refieren todas al mismo hecho, parece más razonable poder declarar una variable con siete elementos, en los que almacenaremos la temperatura máxima de cada uno de los días de la semana:

int [] maxima; // declaración del array maxima

Creación de un Array

En la declaración anterior no se ve el número 7 por ninguna parte, y esto es porque se trata sólo de una declaración, y esto significa que sólo se crea un espacio para contener la referencia al array, no la memoria que contendrá los elementos del array. La memoria necesaria para almacenar los elementos del array se reserva con una sentencia new, como se puede ver a continuación:

maxima = new int[7];  // creacion del array maxima con 7 elementos

El array creado con la sentencia new tendrá todos los elementos inicializados al valor por defecto del tipo de los elementos.

También se puede crear un array mediante la inicialización del mismo. Para ello, se incluye una lista de expresiones separadas por comas y encerrada entre llaves, que serán evaluadas al tipo de los elementos del array. Eso es lo que se hace en la siguiente sentencia, en la que se crea el array maxima con las temperaturas para cada dia de la semana:

int [] maxima = {23,24,22,18,20,24,25};  // inicializacion

El número de componentes de un array se determina cuando se crea, y existe un campo del objeto array que almacena la longitud del array, length. Así, si quisieramos conocer el número de elementos del array maxima podríamos hacerlo con la sentencia

int l=maxima.length;  // l tiene el número de elementos de maxima

La memoria referenciada por la variable array será automáticamente liberada cuando no se necesite más.

Acceso a los Elementos de un Array

Java sigue el estilo de indexado normal de C para el acceso a los elementos de un array; se coloca una expresión de tipo entero entre corchetes tras el nombre del array.

m = maxima[3];  // acceder al cuarto elemento de maxima

El primer elemento de un array tienen el índice 0, y el último será length-1.

Todos los acceso se verificarán para comprobar que se encuentran en el rango permitido. Si el valor está fuera de los límites del array, se producirá una excepción de tipo ArrayIndexOutOfBoundsException (aunque las excepciones se tratarán mas adelante).

Copiar un Array

Como un array es un objeto, la asignación del valor de una variable array a otra sólo copiará la referencia a ese array. Así, se puede copiar el array maxima a maxima2 utilizando la siguiente sentencia:

int [] maxima2 = maxima;   // copiando maxima a maxima2

Arrays Multidimensionales

Un array multidimensional es un array de arrays (cada elemento del array es un array a su vez). Se puede crear un array multidimensional no rectangular si cada elemento de un array se reiere a arrays de diferentes tamaños. Por ejemplo, podemos crear un array de dos dimensiones para almacenar los datos de una matriz cuadrada de dos dimensiones:

int [][] a =  new int [2][2];  // a matriz cuadrada bidimensional

Tambien se pueden utilizar inicializadores para arrays multidimensionales:

int [][] a = {{1,2},{3,4}};  // inicializando a

La primera dimension de un array debe especificarse cuando se crear el array. Las demás dimensiones pueden dejarse sin especificar, para ser rellenadas más tarde.

int [] fila0 = new int[2];   // creacion de la primera fila de a
fila0[0]=1;   // asignacion del primer elemento de fila0
fila0[1]=2;   // asignacion del segundo elemento de fila0
int [] fila1 = {3,4};   // creacion e inicializacion del la segunda fila de a
int [][] a = new int[2][];  // creacion de a
a[0]=fila0;   // copiando fila0 como primer array de a
a[1]=fila1;   // copiando fila0 como segundo array de a

3.7 Expresiones y Operadores

Las expresiones son combinaciones de variables, palabras reservadas, literales, llamadas a métodos y campos, y operadores que son evaluadas y dan como resultado un valor de un determinado tipo de datos. Este valor puede ser un número, un caracter o cualquier otro tipo de datos. El tipo de una expresión está determinado por los tipos de las partes que la componen y la semántica de los operadores.

Un operador es un símbolo que transforma una variable o la combina de alguna otra manera con otra variable o literal. Por ejemplo, la siguiente expresión tiene dos operadores, '=' o asignación y '*' o producto:

a = b * c;

Las expresiones con que actúa un operador se llaman operandos. Existen operadores unarios y binarios, según actuen sobre uno o dos operandos. Por ejemplo, el operador asignación es binario mientras que el '-' es unario en este caso:

a = -d;

3.7.1 Precedencia y Asociatividad de los operadores

La precedencia de los operadores es su 'adherencia' con respecto a los demás. Los operadores tienen diferentes precedencias, lo que establece el orden de evaluación o de aplicación de cada uno de ellos cuando hay más de uno en la misma expresión. La precedencia se puede modificar utilizando los paréntesis '(', ')'.

Cuando aparecen juntos dos operadores con la misma precedencia, la asociatividad determina cuál se evaluará primero.

La siguiente tabla recoge todos los operadores en orden de mayor a menor precedencia. Todos los operadores son binarios excepto los que actuan sobre expr, los operadores de creación y de conversión de tipo, mientras que el operador condicional es ternario. Los operadores con idéntica precedencia aparecen en la misma línea:

postfijos [] . (parámetros) expr++ expr--
unarios ++expr --expr +expr -expr ~ !
creación o conversión new (tipo)expr
multiplicación * / %
suma + -
desplazamiento << >> >>>
relacionales < > <= >= instanceof
igualdad == !=
AND a nivel de bits &
XOR a nivel de bits ^
OR a nivel de bits |
AND lógico &&
OR lógico ||
condicional ?:
Asignación = += -= *= /= %= >>= <<= >>>= &= ^= |=

Todos los operadores binarios que no son de asignación asocian por la izquierda. Los de asignación asocian por la derecha. Lo que hace que

a=b=c;

sea equivalente a

a=(b=c);

3.7.2 Orden de Evaluación

Java garantiza que los operandos en una expresión se evalúan de izquierda a derecha. Así, por ejemplo, en la expresion x + y + z, el compilador evalúa x, evalúa y, suma los dos valores, evalúa z y lo suma al resultado anterior.

El orden de evaluación tiene importancia cuando x, y o z ocasionan efectos colaterales de cualquier tipo. Por ejemplo, si son evocaciones a métodos que afectan al estado de un objeto, o imprimen algo, el resultado variaría dependiendo del orden de evaluación.

Excepto en el caso de los operadores &&, || y ?:, todos los operandos de un operador son evaluados antes de que se realice la operación.

3.7.3 Tipo de la Expresión

Todas las expresiones tienen un tipo de dato. El tipo de una expresión está determinado por los tipos de las partes que la componen y la semántica de los operadores.

Si se aplica un operador aritmético a un valor entero, el resultado es de tipo int, a menos que uno de los dos operandos sea long, en cuyo caso el resultado será long. Todas las operaciones con enteros se realizan con precisión int o long, por lo que los tipos byte y short son promocionados a int antes de ser evaluados.

Si cualquiera de los operandos es un número en punto flotante, la operación se realiza en aritmética de punto flotante. Tales operaciones se hacen en float a menos que uno de los operandos sea double, en cuyo caso se usa double tanto para el cálculo como para el resultado.

Cuando se utiliza un char en una operación aritmética se convierte a int asignando ceros a los 16 bits superiores.

3.7.4 Conversiones de Tipo

Java es un lenguaje de tipado fuerte, lo que significa que comprueba la compatibilidad del tipo en tiempo de compilación en casi todos los casos. Java impide las asignaciones incompatibles y proporciona conversiones cuando la compatibilidad es posible.

Conversiones Implícitas

Algunas conversiones se realizan de manera automática, sin tener que preocuparnos por ellas. Estas se producen cuando utilizamos un tipo de dato más pequeño en lugar de uno más grande, en términos de almacenamiento. Así, podríamos utilizar un int en lugar de un long (pero no al contrario). También se produce una conversión implícita de enteros a punto flotante, pero no a la inversa. Además, un valor en punto flotante se puede asignar a cualquier variable en punto flotante de precisión igual o mayor.

Conversiones Explícitas

Cuando un tipo no se puede asignar a otro con conversión implícita a menudo se puede convertir explícitamente al otro tipo. Una conversión explícita solicita un valor nuevo de un tipo nuevo que sea la mejor representación disponible del valor antiguo en el tipo antiguo. Algunas conversiones no están permitidas, como un boolean a int. Este tipo de conversiones puede llevar asociado la pérdida de precisión y el redondeo.

Las conversiones explícitas se pueden realizar colocando delante del elemento cuyo tipo se quiere cambiar el nuevo tipo entre paréntesis, como se puede apreciar en el siguiente ejemplo.

double d=7.99;
int i=(int)d;

Conversiones de cadenas

La clase String es especial, pues se usa implícitamente en el operador + de concatenación de cadenas. Cuando en la concatenación está un objeto no String Java lo convierte a cadena de caracteres invocando su método toString. Cuando se convierte a cadena de caracteres una referencia nula resulta la cadena "null". Si no hay definido un método toString para una clase, se utiliza uno por defecto, que devuelve una representación del objeto en forma de cadena de caracteres.

3.7.5 Operadores Aritméticos

Operan sobre cualquier tipo de dato numérico, ya sea entero o punto flotante, y producen resultados enteros o de punto flotante. Son

La aritmética de enteros es aritmética modular en complemento a dos, es decir, si un valor excede el rango de su tipo es recucido a su módulo. Por tanto, la aritmética de enteros nunca produce desbordamientos ni subdesbordamientos. La división entre enteros trunca el resto con la siguiente regla: (x/y)*y + x%y == x. La división por cero o el resto por cero no son válidas.

La aritmética de caracteres es aritmética de enteros ya que un char es convertido implícitamente a int.

Java usa el estándar IEEE 754-1985 tanto para la representación como para la aritmética de números en punto flotante. De acuerdo con él, podemos producir desbordamientos hacia el infinito o subdesbordamientos a cero. También se puede representar los resultados de expresiones no válidas, NaN, como la división por cero.

Concatenación de Cadenas de Caracteres

Se puede usar + para concatenar dos cadenas de caracteres:

String ho="ho";
String la= ho + "la";
la += "!";
System.out.println(la);

cuya salida será:

hola!

3.7.6 Operadores de Incremento y Decremento

Los operadores ++ y -- son los operadores de incremento y decremento, respectivamente. La expresión i++ es equivalente a i=i+1, salvo que i se evalúa sólo una vez.

Los operadores de incremento y decremento pueden ser prefijos o postfijos, dependiendo de si aparecen delante o detrás del operando. Si el operador está delante, la operación se realiza antes de que sea devuelto el valor de la expresión. Si está detrás la operación se realiza después de que se haya usado el valor original. Por ejemplo:

class Prepost{
   public static void main(String [] args){
   int i=0;
   System.out.println(++i + " " + i++ + " " + i);
   }
}

produce la salida

1 1 2

Los operadores de incremento y decremento se pueden aplicar también a variables char para obtener el carácter Unicode siguiente o anterior, respectivamente.

3.7.7 Operadores Lógicos, Relacionales y Condicionales

Java soporta un juego estándar de operadores relcionales y de igualdad:

Todos estos operadores dan lugar a valores boolean. El operador unario ! convierte un valor lógico en el complementario, !true es igual a false. Los operadores == y != son los únicos que pueden comparar operandos booleanos. Los demás tipos se comparan de forma natural.

Dos referencias se pueden comparar siempre a efectos de igualdad. ref1 == ref2 será true cuando se refieran al mismo objeto o cuando ambas sean null. En caso contrario serán false.

Para comparar la igualdad de dos objetos de tipo String hay que utilizar el método String.equals ya que la comparación con el operador == compararía la referencia, no el contenido de los objetos.

Los resultados de expresiones booleanas se pueden combinar con otros resultados para componer expresiones más complejas utilizando las siguientes conectivas:

Estos operadores intentan evitar evaluar el segundo operando si es posible, de modo que en la expresión x && y la variable y será evaluada sólo si x es true, ya que en otro caso la expresión será siempre false.

Java ha mantenido el operador condicional de asignación del C: ?:. Este operador es ternario:

variable = (condición ? valor1 : valor2);

El primer operando es de tipo boolean, y los otros dos pueden ser de cualquier tipo compatible con la variable a la que se asignará uno de ellos dependiendo del valor de la condición. Si la condición es true el valor de la expresión será valor1, si el false será valor2.

int a=1,b=2,menor;
menor=(a<b?a:b);  // menor contendrá el menor de a y b

3.7.8 Operadores de Campos de Bits

Los operadores binarios a nivel de bits se pueden usar sólo con datos enteros o booleanos:

Ejemplos de sentencias que utilizan estos operandos son:

int a=1;
int b;
 
b=a<<1;
System.out.println("a << 1 = " + b);
b=a<<2;
System.out.println("a << 2 = " + b);
b=a & 0x00000000;
System.out.println("a & 0x00000000 = " + b);
b=a | 0x00000000;
System.out.println("a | 0x00000000 = " + b);

cuyos resultados serán;

a << 1 = 2
a << 2 = 4
a & 0x00000000 = 0
a | 0x00000000 = 1

Los operadores booleanos a nivel de bits, & y | se pueden usar también sobre valores boolean, devolviendo el mismo valor que sus homólogos lógicos && y ||, aunque con una diferencia: los operadores a nivel de bit evalúan siempre los dos operandos.

3.7.9 Operadores de Asignación

El operador asignación más elemental es =, y su cometido es asignar el operando derecho al izquierdo, y devolver el derecho como resultado. Cualquier otro operando aritmético o de nivel de bits binario puede combinarse con = para formar otro operador de asignación.

Así, la expresión b += a es equivalente b = b + a, sólo que en la primera versión b se evalúa sólo una vez.

3.8 Bibliografía


Jesús Vegas
Dpto. Informática
Universidad de Valladolid
jvegas@infor.uva.es