Recordemos algo de JAVA y lenguajes de programación, antes de continuar
Resumen basado en mis autoaprendizaje de varios lenguajes, video tutoriales, libros, documentos de internet etc, se aceptan sugerencias, mejoras, correcciones etc
INTRODUCCION
1: DATOS
Un programa informático gestiona datos sobre una maquina computacional (computador/ordenador, calculadora, sistema embebido, PLC, etc.), los datos pueden estar incorporados dentro del programa, o pueden ser obtenidos en el transcurso de su ejecución, ya sea por medio de un usuario o automata, en el primer caso usa por ejemplo un teclado real o virtual, selección de un archivo almacenado en el disco duro o dispositivo externo, en el segundo caso la entrada de datos puede ser automática, adquirida por un sensor electrónico, un correo o teléfono celular que envía datos programados, a través de un interface electronica y/o aplicación de software etc.
Las maquinas computacionales se crearon para "entender" un alfabeto binario "0" y "1"ya que su hardware se basa en un lógica simple de dos estados, en palabras no complejas es ausencia o no de una señal eléctrica, es imposible hasta ahora crear maquinas computacionales para operar sobre un alfabeto completo, tendría un capacidad de razonamiento similar al ser humano tal ves algún día llegaremos a un tipo de inteligencia artificial similar a la nuestra
Los datos al final se convierten en cadenas de números binarios para que puedan ser interpretados por el procesador, pero lo que nos interesa por ahora es el código de programa o código fuente y lo especial o mágico es que tan solo se requiere para ser codificado un poco menos de los 95 caracteres imprimibles o visibles del ASCII. o (Código Estándar Estadounidense para el Intercambio de Información)
lista de caracteres visibles del ASCII
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _
` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
Lenguajes modernos como JAVA puede gestionar caracteres Unicode, es decir caracteres especiales o no disponibles en ASCII, para poder visualizar símbolos de lenguajes naturales como JAPONES, ESPAÑOL, ARABE etc
además de símbolos matemáticos como ∂ ∫ ∬ ≠, símbolos técnicos, etc.
Sobre los lenguajes de programación, abarcan desde el lenguaje de maquina o código final para el procesador que son cadenas de dígitos binarios, luego esta el lenguaje ensamblador o conocido también como lenguaje de bajo nivel, que se caracteriza por un nivel complejo de sintaxis en el código fuente y difícil interpretación humana para llevar la lógica de un problema a código fuente, pero con la ventaja de que el programa compilado o ejecutable sera el mas optimo con respecto a velocidad de ejecución del siguiente caso, el cual es lenguaje de alto nivel, se codifica por lo general en instrucciones que en su mayoría son palabras tomadas del idioma INGLES, usa operadores aritméticos que en gran parte son idénticos a los símbolos matemáticos « x +, -, /, <, > », otros no lo son porque por ejemplo en ASCCI no existe el símbolo MAYOR o MENOR E IGUAL QUE, entonces se requiere la combinación de al menos dos símbolos (DIGRAPHS) ASCCI como « >= », « <= » para hacer equivalencia a los verdaderos símbolos aritméticos ≦ ≧, usa también operadores que no se definen en la aritmética, como incremento « ++ », decremento « -- », y otros son cruzados como « % », que no significa porcentaje, sino residuo o modulo de la division aritmética y su expresión es x mod y, similarmente en aritmética el símbolo « ! » es factorial, mientras que en java es negación de una expresión boleana
Los lenguajes de alto nivel no los puede interpretar los procesadores, requieren convertirse y para esto necesitan bibliotecas o paquetes con cientos de subrutinas, implica que el código ejecutable creado sea mas grande y redundante con respecto si se crease el código desde un lenguaje ensamblador.
Los lenguajes interpretados, son dos tipos, unos que en tiempo real toman cada sentencia y llaman a funciones internas de interpretación como el QBASIC (version antigua, por que la actual es compilada), otros como es el caso de java compila el código fuente, y crea un código ejecutable (ByteCode) que requiere una capa por software o también llamada MAQUINA VIRTUAL COMPUTACIONAL, esto con el propósito de ser ejecutable sobre cualquier marca y tipo de procesador desde ordenadores, celulares, relojes a tabletspc
Sobre los compiladores son de 2 tipos, los que generan el código ejecutable para el mismo tipo de procesador y el otro para otro procesador distinto a aquél en la que el compilador se ejecuta, este tipo de compilador se denomina compilador cruzado, los IDEs de java son de este tipo
El principal objetivo de un programa es gestionar números (enteros en formato decimal, octal, hexadecimal y números decimales (en forma de coma o punto flotante), también los lenguajes pueden operan cadenas de texto, pero necesitan contenedores para diferenciarlas de las sentencias o conjuntos de instrucciones de un lenguaje de programación, estos contenedores son en su mayoría un par de comillas dobles « " " » o simples « ' ' ». Las comillas dobles son para encerrar textos mas de un carácter y comillas simples para encerrar un solo carácter, el primer contenedor se dice que es el contenedor de abertura y el final de cierre, al igual que los paréntesis en aritmética no pueden estar un solo, se requiere siempre uno de apertura y otro de cierre, si elimínanos el primer paréntesis o paréntesis de apertura de 2*(3 + 1) se obtiene 2*3+1) que cambia el resultado de la expresión o genera un error de sintaxis, análogamente para (2^31)-1, si eliminamos el segundo paréntesis o paréntesis de cierre se obtiene otro resultado (2^31-1
Ejemplo
"x = 2*(3 + 1)" es un texto que puede significar una formula en un libro de texto, mientras que
x = 2*(3 + 1) ; es una sentencia de programación que en C/C++/C#/java y otros es una operación de asignación que usa el operador igual « = » para almacenar en la variable « x » el resultado de la evaluación de expresión del lado derecho « 2*(3 + 1)" » que además contiene el operador suma y dos números enteros
mientras que '=', '+', 'x', '1' '3' '2' '*' son interpretados solo como caracteres
Algunos lenguajes también operan sobre conjuntos de datos del mismo tipo, llamados « ARRAYS » como arreglos de números enteros, e incluso arreglos de cadenas de texto, y muchos lenguajes llegan hasta este punto, el poder de los lenguajes modernos es que pueden gestionar estructuras de datos que simulan objetos de la realidad, como cuentas de usuario de bancos, cuentas de usuario de internet, objetos matemáticos para crear kernels de algebra simbólica etc.
El objeto mas simple y común en java se denomina la CLASE STRING, antes de hablar de la clase STRING, se necesita el concepto de VARIABLE o IDENTIFICADOR
2: VARIABLE o IDENTIFICADOR (ID)
Este es un nombre que identifica un dato dentro de un código fuente, pero que dentro del código ejecutable UBICA el dato u objeto en la memoria física del sistema computacional. Dentro del código fuente el ID es tan solo un nombre o secuencia de caracteres ASCII con ciertas reglas de construcción, la mas importante es que no debe llamarse como un nombre del conjunto de instrucciones propio del lenguaje y la segunda mas importante es que no debe contener el carácter espacio ' ', además de otras condiciones que se exploraran próximamente.
El nombre ID puede contener n caracteres de longitud para servir como base de identificación rápida y auto-documentación del código fuente, a mayor numero de caracteres mayor sera el tamaño del código de fuente,
es una mala practica de programación, la cual es crear identificadores con nombre cortos, ya que se desconoce que dentro del código ejecutable el identificador al igual que todo el resto es tan solo una cadena de números binarios, en donde cada identificador se convierte en dirección de memoria de pocos bytes de tamaño.
ejemplo
usarioN1 es un ID valido y mejor que u1,
usarioN1 y u1 podría contener un nombre de persona y como se dijo anteriormente un texto o mejor en la jerga de JAVA una cadena o secuencia de caracteres de caracteres « String » debe ser contenida por doble par de comillas
usarioN1 = "Juan";
u1 = "Jaime";
usarioN1 puede tener como ubicación o dirección 0x3A98 y u1 la dirección siguiente en +/- 1 o n bytes, por esta razón la longitud del nombre identificador no implica mas o menos tamaño de memoria requerida, mientras que el contenido del ID si aumenta o disminuye el tamaño de memoria en ciertos tipos de datos, en especial los « String »
2.1: ALMACENAMINETO DINAMICO
Primera característica del objeto STRING, se almacena en un campo de memoria dinámica
veamos
Si en el trascurso de un programa el contenido de usarioN1 es el primer nombre y luego se expande incluyendo un segundo nombre y apellido tenemos
usarioN1 = "Juan Camilo Salazar";
y luego un segundo apellido
usarioN1 = "Juan David Salazar Ortiz";
vemos que en el caso del nombre de usuario la memoria que necesita para contener cada caso se incrementa, si cada carácter UNICODE se codifica en 16 bits o 2 Bytes, la primer asignación (usarioN1 = "Juan"; ) se almacena "Juan" que posee los siguientes caracteres 'J', 'u', 'a' 'n' este requiere 4*2 Bytes, es decir 8 bytes de memoria , mientras que "Juan David Salazar Ortiz" ocupa 24 bytes, incluyendo el carácter espacio, por lo tanto usarioN1 requiere almacenamiento dinámico, es decir que crezca o disminuya la cantidad de espacio en memoria requerida al redefinir el contenido de la variable en la ejecución del programa
2.2: ALMACENAMINETO ESTATICO
El caso contrario es que el contenido final del ID varié, en este caso en JAVA ocupa el mismo tamaño de memoria veamos
en el ejemplo de arriba la sentencia x = 2*(3 + 1);
también pude cambiar de contenido de 8 a 20mil
x = 2*(3 + 1);
x = 10000*2;
aparentemente se requiere mas memoria para contener 20000 que 8, pero No es así y esto también depende del tipo de lenguaje, pero antes de explicar el porque ocupan el mismo tamaño 20,000 que 8 veamos el siguiente punto
3: INTRODUCCION A LOS TIPOS de DATOS
la siguiente sentencia, usarioN1 contiene un String, ahora se desea almacenar un tipo de dato diferente
usarioN1 = 10000*2;
no es posible en muchos lenguajes porque en un principio usarioN1 contenía una cadena de caracteres, luego transmuto a un numero entero, para evitar esta ambigüedad de contenido las variables o identificadores requieren una ayuda para evitarla, la ayuda es una palabra clave como prefijo o antes del nombre ID, este prefijo se denomina TIPO de dato
ejemplo
String usarioN1 = "Juan David Salazar Ortiz";
int x = 10000*2;
usarioN1 = 10000*2;
ahora usarioN1 le dice al compilador y revisor del programa en tiempo real que « usarioN1 » solo acepta CADENAS o STRINGs de caracteres y no otra cosa, al igual que « x » solo acepta números enteros, entonces el compilador cuando llega a la expresión usarioN1 = 10000*2; se detiene y genera un error de compilación, "dato invalido"
4: RANGO DE algunos TIPOS DE DATOS en JAVA
Para mejorar la eficacia de un programa se ideo la forma de limitar el contenido de ciertos tipos de datos, por ejemplo en JAVA, el tipo de dato int (entero por defecto en JAVA, usa 4 Bytes (32 bits) de memoria)
Recordemos que la minima cantidad de dígitos para conformar números son dos (base binaria), podemos hacer algebra y aritmética y esta fue desarrollada por GEORGE BOOLE de ahi su nombre, algebra de Boole, una forma didáctica de crear números en base 2 es pensar todos los números que tienen 1s y 0s de la base 10, se inicia con el 0, luego 1, luego 10, luego 11, 100, 101, 110, 111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111, ... etc
0 0
1 1
10 2
11 3
100 4
101 5
110 6
111 7
1000 8
1001 9
1010 10
1011 11
1100 12
1101 13
1110 14
1111 15
10000 16
...
de la lista anterior podemos observar que
Con 1 dígitos o bits se pueden conformar 2^1 = 2 números, 0 y 1
Con 2 dígitos o bits se pueden conformar 2^2 = 4 números, 00, 01, 10, 11
Con 3 dígitos o bits se pueden conformar 2^3 = 8 números, 000, 001, 010, 011, 100, 101, 110, 111
en forma general con N bits se pueden representar 2^(#bits) números
como 1 Byte son 8 bits entonces para un « int » se tiene que 2^(4*8 ) = 4,294,967,296, es decir el rango contiene mas de 4,200 millones de números, pero como hay que repartirlos (partirlos por la mitad) en negativos y positivos, mas el numero 0, entonces el menor numero se define por la expresión 2^(#bits-1) y el mayor como 2^(#bits-1)-1
solo permite contener números entre -2^31 que es igual a -2,147,483,648 y (2^31)-1 que a su ves es 2,147,483,647, paso a paso evaluado el rango, note que si disminuimos el exponente en 1 se divide el valor en 2
[ -2^(#bits-1), .... , 0 , ... , 2^(#bits-1)-1 ] =
[ -2^((4*8 )-1), .... , 0 , ... , 2^((4*8 )-1)-1 ] = [ -2^(32-1), ..... , 0 , ... , 2^(32-1)-1 ] =
[ -2^31, ..... , 0 , ... , 2^(31)-1 ] =
El rango de « int » es[ -2,147,483,648, .... , 0 , ... , 2,147,483,647 ]
si sumamos los valores absolutos extremos tenemos |-2,147,483,648 |+|2,147,483,647 | +1 (del cero) se comprueba el total de valores 4,294,967,296
Ejemplo practico
las siguientes sentencias son validas, por estar dentro del rango permitido
int x = -2147483648;
int x = 0;
int x = 10000*2;
int x = 2147483647;
y las siguientes sentencias NO son validas por desbordarse en solo 1 unidad
int x = -2147483648-1;
int x = 2147483647+1;
o su resultado equivalente
int x = -2147483649;
int x = -2147483649;
int x = 2147483648;
si se sabe que el ID puede contener un numero entero mas grande, existe el tipo de dato « long » (entero largo que en java usa 8 Bytes de memoria)
si se redefine el tipo de dato las sentencias anteriores son validas
long x = -2147483648-1;
long x = 2147483647+1;
entonces si se conoce que la variable no superara el rango entre [ -2,147,483,648, .... , 0 , ... , 2,147,483,647 ] se debe definir como « int » ya que solo ocuparía 4 bytes, no tiene sentido definirla como « long », que ocuparía 4 Bytes mas, el doble por cada sentencia
En resumen las 4 sentencias siguientes, ocupan el mismo tamaño en memoria (4 Bytes), no depende del contenido de la misma y esto responde la inquietud pendiente de arriba
int x = -2147483648;
int x = 0;
int x = 10000*2;
int x = 2147483647;
el máximo numero que puede procesar JAVA es un REAL cuyo tipo de dato es (double) y valor máximo 1.8*10^308
que se codifica como coma o punto flotante.
int r = 1.8E308D;
IMPORTANCIA DEL OBJETO STRING
ahora se preguntan si la lógica del programa requiere operar un numero mas grande que 1.8*10^308, por ejemplo algoritmo que calcule distancias astronómicas (nave espacial que va hasta pluton y mas allá), ¿que podemos hacer? una manera es operar un numero como cadenas de caracteres STRINGs, existen códigos en java creados por terceros para este fin.
En la lógica de un programa requiere manipular no solo números, si no también cadenas de caracteres, los lenguajes comunes no tienen funciones para operar cadenas, por esta razón JAVA interpreta una cadena de caracteres como OBJETO y como un objeto es una clase especializada, esta contiene varias funciones que ayudan a codificar rápidamente sin la necesidad de crear bibliotecas de usuario para la manipulación de strings,
algunas funciones de la clase String, son: convertir numero entero como cadena en numero de tipo entero (función de cadena a numero) y viceversa (función de numero a cadena), convertir cadena a mayúsculas o minúsculas, hallar la posición de un carácter dentro de la cadena y muchas otras mas.
Próximamente se incluirá un ejemplo
Como buena practica de programación se recomienda adherir un prefijo al nombre del identificador o variable, por ejemplo str para String, int para int, lng para Long etc
String strCadena1 = "Hello World Again";
int intContador1 = 256;
5: TIPOS DE IDENTIFICADORES O VARIABLES
Existen dos tipos de identificadores, Identificador o variable primitiva y Identificador de variable referencia
El identificador que hace referencia a un objeto primitivo como « int intContador1 = 256; » se denomina Id primitivo o variable primitiva
El identificador que hace referencia a un objeto como « String strCadena1 = "Hello World Again"; » se denomina ID referencia o variable referencia
Las variables primitivas y variables referencia también pueden contener ARREGLOS o conjunto de datos, se dice Arreglos de variable primitiva o Arreglos variable referencia, se requiere un postfijo después del nombre de ID o en el tipo de dato el cual es un contenedor tipo paréntesis angular o comúnmente conocido como corchete de apertura y cierre « [ ] » para diferenciar ID que contiene un solo dato o ID que permite almacenar un conjunto de datos
Ejemplos
« int intContador1[] = {256, 257, 258} ; »
« String strCadena1[] = { "Hello", "World", "Again" } ; »
es equivalente a
« int[] intContador1 = {256, 257, 258}; »
« String[] strCadena1 = { "Hello", "World", "Again" } ; »
6: TIPOS DE DATOS PRIMITIVOS o BASICOS en JAVA
como dijimos anteriormente son datos básicos del lenguaje, JAVA opera con números ENTEROS y REALES de forma básica y también los mismo pero visto como objetos, primero estudiaremos los BASICOS
6.1: TIPOS DE DATOS PRIMITIVOS ENTEROS
Son 4 tipos de datos primitivos « byte, short, int, long », se diferencian por que cada uno puede contener un rango diferente de números, esto depende del numero de BYTES de uso de cada tipo
el tipo con menor rango es el que usa un 1 byte (8 bits) ya que es el mínimo elemento de memoria direccionable de algunas maquina computacional
con los ejemplos de arriba de la introducción de tipos de datos, podemos construir las formulas para cada tipo primitivo entero
menor numero del rango: valor mínimo = -2^(#bits-1)
mayor numero del rango: valor máximo = (2^(#bits-1))-1
La cantidad de números del rango del tipo de dato: rango = 2^(#bits)
rango = |valor mínimo | + |valor máximo| + 1
tenemos para 8 bits o 1 Byte
rango = 2^(#bits) = 2^8 = 256 valores
valor mínimo = -2^(8-1) = 2^7 = -128
valor máximo = (2^(8-1))-1 = (2^7)-1 = 127
prueba del rango |-128| + |127| +1 = 256 valores
Entonces podemos definir el tipo de dato « byte » rango = [-128, ..., 0, ..., 127], usado en plataformas básicas de 8 bits similarmente se define para los demas
Resumen de NUMEROS ENTEROS EN JAVA
Con 8 bits (1 byte) se pueden conformar 2^8 = 256 números, tipo en JAVA « byte »
Con 16 bits (2 byte) se pueden conformar 2^16 = 65536 números, tipo en JAVA « short » ENTERO CORTO
Con 32 bits (4 byte) se pueden conformar 2^36 = 4294967296 números, tipo en JAVA « int » ENTERO (valor por defecto)
Con 64 bits (8 byte) se pueden conformar 2^64 = 4294967296 números, tipo en JAVA « long » ENTERO LARGO
RESUMEN de los RANGOS de NUMEROS ENTEROS
byte = [ -128, ..., 0, ..., 127 ] = [ -2^7, +(2^7)-1]
short = [ -32,768, ..., 0, ..., 32,767 ] = [ -2^15, +(2^15)-1]
int = [ -2,147,483,648, ..., 0, ..., 2,147,483,647 ] = [ -2^31, +(2^31)-1]
long = [ -9,223,372,036,854,775,808, ..., 0, ..., 9,223,372,036,854,775,807] = [ -2^63, +(2^63)-1]
Ejemplo practico
public class clAprendiendoJava {
public static void main
(String[] args
) {
byte byte_minimoEntero;
short shr_enteroCorto;
int int_enteroPorDefecto;
long int_enteroLargo;
byte_minimoEntero = (byte) 127;
shr_enteroCorto = 32767;
int_enteroPorDefecto = 2147483647;
int_enteroLargo = 9223372036854775807L;
printConsole("Minimo Entero: " + byte_minimoEntero);
printConsole("Entero Corto: " + shr_enteroCorto);
printConsole("Entero por Defecto: " + int_enteroPorDefecto);
printConsole("Entero largo: " + int_enteroLargo);
}
public static void printConsole
(String str
) { }
}
6.2: TIPOS DE DATOS PRIMITIVOS REALES
en redacción ...
6.3: TIPOS DE DATOS PRIMITIVOS BOOLEAN (LÓGICAS): Este tipo de datos solo permiten almacenar 2 valores contantes « true » verdadero y « false » falso, otros lenguajes usan el numero 0 como valor falso y el resto de números enteros como verdadero
6.4: TIPOS DE DATOS PRIMITIVOS CHARACTER (CARÁCTER): Este tipo de datos solo permiten almacenar caracteres de la tabla UNICODE en formato de 16 bits, implica 2^16 = 65,536 caracteres , en contraposición de los 127 de ASCII usados en otros lenguajes, un carater como se dijo anteriormente requiere un contenedor « ' ' » para almacenar un solo caracter o numero hexadecimal de 4 digitos en formato « ' \uxxxx' »
char chrLetra_A = 'A';
char chrLetra_a = 'a';
char chrLetra_0 = '0';
char chrLetra_9 = '9';
char chrSimbolo_plus = '+';
char chrSimbolo_derivada = '∂';
char chrSimbolo_e = '∃';
char chrSimbolo_integral = '∫';
char chrSimbolo_integralDoble = '∬';
char chrSimbolo_diferente = '≠';
// en formato numérico hexadecimal
char chrLetra_A_ = '\u0041';
char chrLetra_a_ = '\u0061';
char chrLetra_0_ = '\u0030';
char chrLetra_9_ = '\u0039';
char chrSimbolo_plus_ = '\u002B';
printConsole("chars: " + chrLetra_A + " " + chrLetra_a + " " + chrLetra_0 + " " + chrLetra_9 + " " + chrSimbolo_plus);
printConsole("chars: " + chrSimbolo_e + " " + chrSimbolo_derivada + " " + chrSimbolo_integral + " " + chrSimbolo_integralDoble + " " + chrSimbolo_diferente);
printConsole("chars: " + chrLetra_A_ + " " + chrLetra_a_ + " " + chrLetra_0_ + " " + chrLetra_9_ + " " + chrSimbolo_plus_);
salida
chars: A a 0 9 +
chars: ∃ ∂ ∫ ∬ ≠
chars: A a 0 9 +
Hay algunos caracteres que no son visibles en UNICODE y ASCII como LINEA SIGUIENTE, TABULADOR y otros caracteres que son parte del lenguaje como « ' » « " » , no se puede definir los siguiente
char chrSimbolo_comilla simple_ = ' ' ';
por que un par de comillas es un contenedor, al introducir una comilla simple dentro del contenedor, JAVA lo interpreta como contendor desbalanceado por que hace falta un contenedor par igualar el par
se ideo que el carácter barra inclinada hacia la izquierda indica que le próximo carácter es valido dentro de un contenedor de comillas simples
\' indica carácter de comilla simple
\" indica carácter de comilla doble
y para especificar la misma barra inclinada hacia la izquierda
\\ indica carácter de barra inclinada hacia la izquierda
\uXXXX indica carácter de l código unicode en formato Hexadecimal, máximo 16 bits
otros caracteres No visibles o accesibles por teclado
\0 indica el 1er carácter del código UNICODE
\t indica carácter tabulación
\n indica carácter nueva línea
7: TIPOS EVOLVENTES o TIPOS BASICOS como OBJETOS
La programación orientada a objetos introdujo un nuevo tipo de datos, tipos no como simples datos primitivos o básicos, sino tipos de datos de referencia a objetos, algunos tipos de datos primitivos en JAVA son int, long float, double, mientras tipos de datos de referencia a objetos son Integer, Long, Float, Double, String se diferencia a simple vista de los tipos primitivos por que inician en carácter o letra Mayúscula y son palabras completas « int » versus « Integer », « float » versus « Float » , para cadenas de caracteres no hay tipo de básico o primitivo, solo tipos de datos de referencia a objeto CADENA, llamado « String »
Próximamente e incluirá un ejemplo
redactando ...