Python » Miscelánea » Python vs Java: Comparación a fondo

Python vs Java: Comparación a fondo

En este artículo vamos a ver una comparación detallada entre los lenguajes de programación Python y Java. En concreto nos centraremos en su popularidad respecto a otros lenguajes de programación, sus características fundamentales, y qué tipo de aplicaciones se desarrollan con ambos. Además, también veremos con ejemplos de código las principales diferencias que existen en distintos aspectos de su sintaxis, por ejemplo, cómo se realizan los comentarios, cómo se tratan las variables, entre otros. Para escribir este artículo, como buen ex-académico que soy, me he basado principalmente en el paper: Comparative Analysis of Python and Java for Beginners, publicado en el año 2020 en el International Research Journal of Engineering and Technology (IRJET). Te lo he dejado enlazado por si entiendes inglés y quieres profundizar más en la materia.

Popularidad de Python y Java

Basándonos en los resultados de varios índices que miden la popularidad de los distintos lenguajes de programación, podemos concluir que una comparación entre Python y Java resulta muy pertinente ya que estamos ante dos de los lenguajes mejor clasificados y más demandados. Entre estos índices tenemos:

  • El índice PYPL (PopularitY of Programming Language), el cual se basa en cuántas veces se realiza una búsqueda en Google sobre un tutorial de un determinado lenguaje de programación. Según este índice los dos lenguajes de programación más buscados son Python y Java, en este orden.
  • El ranking anual de lenguajes de programación realizado por la revista científica IEEE Spectrum. Este ranking combina factores de distintas fuentes de datos, y también concluye que Python y Java son los dos lenguajes más populares.
  • La encuesta anual de la web Stack Overflow a sus usuarios. En el año 2021, Python y Java quedaron respectivamente en el tercer y quinto puesto de las tecnologías más populares.

Visión general de ambos lenguajes

Python

Python es un lenguaje de programación de tipo general, es decir, está pensado para desarrollar software en una amplia variedad de dominios. Además, destaca por enfatizar en la legibilidad del código y para ello se hace valer de dos recursos: la sangría (con espaciados y/o tabulaciones) y el uso de muchas palabras en inglés.

Python fue creado por Guido van Rossum como un sucesor del lenguaje de programación ABC, y el nombre se lo dio en honor al grupo humorístico británico Monty Python. Su concepción tuvo lugar a finales de los años 80, pero no fue hasta el año 1991 que se hizo público.

El uso de Python es libre, pero su propiedad intelectual pertenece a la Python Software Foundation (PSF), una organización sin ánimo de lucro que se ocupa, entre otras cosas, de su desarrollo y mantenimiento, introduciéndole mejoras en cada nueva versión que sacan.

Java

Java es un lenguaje de programación de alto nivel, orientado a objetos, y también de propósito general. Su filosofía es la de escribir una vez y ejecutar en cualquier lugar (write once, run anywhere). Es decir, que no se tenga que compilar el código para cada tipo de sistema en el que se va a ejecutar. Para ello se hace valer de la llamada máquina virtual de Java, que no es más que un programa encargado de ejecutar el código Java compilado.

El creador principal de Java fue James Gosling, junto con otros empleados de la extinta empresa estadounidense Sun Microsystems. Su desarrollo empezó en 1991, pero la primera versión vio la luz en 1995. Aunque inicialmente la llamaron de forma distinta, sus creadores se decantaron finalmente por Java aludiendo una variedad de café de la isla homónima. De ahí también que su logotipo sea una taza de café.

Inicialmente su propiedad intelectual pertenecía a la empresa Sun Microsystems, y se podía utilizar libremente. Sin embargo, Sun fue adquirida por Oracle en el año 2010 y con ello se apropió también de la implementación oficial de Java. Actualmente su uso en aplicaciones comerciales está sujeto a una licencia de pago.

Características principales

Python

  • Fácil: es un lenguaje de programación fácil de aprender. Además el código en Python es de buen leer en comparación con otros lenguajes como Java, C, C++, etc.
  • Expresivo: es capaz de ejecutar acciones con menos líneas de código que otros lenguajes de programación.
  • Gratuito y de código abierto: todo el mundo puede descargar Python para instalarlo, utilizarlo y redistribuirlo.
  • Alto nivel: programar en Python no requiere conocimientos sobre la gestión de la memoria en una computadora.
  • Portable: un programa desarrollado en Python se puede ejecutar en distintos sistemas operativos, siempre y cuando se tengan en cuenta las características dependientes del sistema.
  • Interpretado: el código Python no requiere compilación, el intérprete de Python lo ejecuta línea a línea.
  • Orientado a objetos: Python soporta un enfoque orientado a objetos, ayudando al programador a escribir código reutilizable.
  • Amplia librería estándar: la librería estándar de Python proporciona una gran variedad de módulos y funciones que el programador puede utilizar importándolas en sus programas.
  • Tipado dinámico: Python no requiere especificar el tipo de dato cuando se declara una variable. El tipo de una variable se decide durante la ejecución del programa.

Java

  • Orientado a objetos: Java está totalmente orientado a objetos, incorporando de serie conceptos como herencia, polimorfismo, abstracción y encapsulación.
  • Independiente de la plataforma: al compilar código Java se crea un bytecode cuya ejecución la lleva a cabo la máquina virtual de Java (JVM). Por tanto, el mismo código lo pueden ejecutar JVMs en distintos sistemas.
  • Seguro: Java es seguro por tener su propio entorno de ejecución (la JVM), comprobar los tipos de las variables en compilación, y su ausencia de punteros.
  • Robusto: Java se encarga de eliminar de la memoria los objetos que no se utilizan. Además, incorpora el manejo de excepciones.
  • Portable: el bytecode de Java se puede transferir tal cual de una máquina a otra.
  • Multi-hilo: Java incorpora características para manejar tareas multihilo, permitiendo crear aplicaciones eficientes que realizan múltiples tareas a la vez.
  • Distribuido: Java permite compartir datos e invocar métodos de manera remota entre programas distribuidos en una red de computadoras.

Diferencias fundamentales entre ambos

Basándonos en los puntos anteriores, podemos concluir que en cuanto a velocidad de ejecución Java es más rápido que Python. Esto es debido a que Java es un lenguaje compilado que usa un tipado estático, mientras que Python es un lenguaje interpretado que usa un tipado dinámico.

Por otro lado, Python es más sencillo y fácil de aprender que Java, especialmente para personas que se inician en la programación. Ya que, generalmente Python requiere menos líneas de código que Java para realizar la misma tarea. Esto lo podemos ver comparando la implementación del programa Hola Mundo en ambos lenguajes.

En Python sólo requiere una línea de código:

print("¡Hola, mundo!")

En Java, aparte de requerir más líneas de código, el nombre de archivo ha de coincidir con el nombre de la clase, de modo que el siguiente fichero ha de llamarse forzosamente HolaMundo.java para que compile:

class HolaMundo {
    public static void main(String[] args) {
        System.out.println("¡Hola, mundo!"); 
    }
}

Más adelante vamos a ver con más detalle las diferencias de sintaxis entre ambos lenguajes de programación.

Aplicaciones de Python y Java

Python

Gracias a su ecosistema de librerías, Python se utiliza para desarrollar software en varios campos. Algunos de éstos son los siguientes:

  • Data science y visualización de datos: Python es una opción popular en este campo gracias a librerías como NumPy, Pandas y Matplotlib.
  • Machine learning: algunas de las librerías existentes para desarrollar algoritmos de machine learning son Keras, TensorFlow y Scikit-learn.
  • Web Scraping: Python es una excelente opción cuando se trata de extraer grandes cantidades de información de sitios web gracias a librerías como Requests, Beautiful Soup, y Scrapy.
  • Desarrollo Web: las dos librerías más conocidas para el desarrollo de backend son Django y Flask, aunque también existen alternativas como Bottle.
  • Aplicaciones GUI: la librería estándar de Python incluye el módulo Tkinter para realizar aplicaciones gráficas de escritorio, pero también hay otras librerías como PyQt y wxPython.
  • Videojuegos: aunque Python no sea una opción muy potente para la creación de videojuegos, tiene librerías que ayudan a ello como Pygame, PyKyra, y Pyglet.

Java

Java también se utiliza para desarrollar aplicaciones en numerosos campos en la vida real, entre los que se encuentran:

  • Desarrollo Web: Java es muy utilizado para desarrollo de backend y existen varios frameworks para ello. Entre todas las alternativas, la más conocida y la que tiene una mayor comunidad de usuarios es probablemente Spring.
  • Aplicaciones GUI: Java proporciona varios paquetes como AWT, JavaFx, y Swing para la implementación de aplicaciones de escritorio.
  • Apps móviles: Java fue lenguaje de programación oficial para el desarrollo de aplicaciones nativas en Android. Ahora el lenguaje oficial es Kotlin, pero se puede seguir usando Java para desarrollar en Android.
  • Big data: un framework muy conocido dentro del mundo de big data es Hadoop, el cual está escrito enteramente en Java.
  • Servidores en finanzas: Java es uno de los lenguajes de programación más utilizados en el sector bancario, así que cuando pagas con tarjeta puede que un servidor desarrollado en Java esté involucrado en la transacción.
  • Sistemas embebidos: Oracle ha creado la versión Java SE Embedded junto con su máquina virtual optimizada para sistemas embebidos.

Diferencias en la sintaxis

En este apartado vamos a ver con ejemplos de código cómo enfocan Python y Java un total de doce elementos de su sintaxis.

Comentarios

En los lenguajes de programación los comentarios se utilizan para explicar el código y hacerlo más legible. Éstos pueden ser de una sola línea o de múltiples líneas. En Python los comentarios de una línea empiezan con el símbolo #. Para comentarios multílinea se puede empezar cada línea con un # o emplear dobles comillas triples o comillas simples triples.

# Esto es un comentario en Python
print("Hola, Python!")
"""Esto es un comentario largo
que ocupa más de una línea"""

En Java los comentarios de una línea empiezan con //, y los comentarios multilínea empiezan con /* y terminan con */. Todo el texto que quede entre ambos símbolos se considera un comentario.

// Esto es un comentario en Java
System.out.println("Hola, Java!");
/* Esto es un comentario largo
que ocupa más de una línea */

Separación de líneas

Python no utiliza ningún símbolo específico para indicar el fin de una línea y cada nueva línea de código se interpreta como tal.

nombre = "HAL"
print("Hola, me llamo", nombre)

En Java cada fin de línea se indica con un punto y coma ; excepto cuando se empieza un bloque de código tal y como veremos en el siguiente punto.

String nombre = "HAL";
System.out.println("Hola, me llamo " + nombre);

Bloques de código

Por bloques de código nos referimos a funciones, sentencias condicionales, bucles, etc. En Python se utiliza la indentación para indicar que las líneas de código pertenecen a un determinado bloque. Este espaciado hace que el código sea fácil de leer.

for x in range(10):
    print(x)

En Java los bloques de código se delimitan mediante llaves {}. Todo el código que esté dentro se entiende que pertenece a esa función, bucle, etc. y no requiere indentación aunque se recomienda su uso para que el código sea más legible.

for (int i = 0; i < 10; i++) {
    System.out.println(i);
}

Imprimir cadenas de texto

Como hemos visto en ejemplos anteriores, Python utiliza la función print() para mostrar cadenas de texto al usuario. Para concatenar texto dentro de dicha función se puede utilizar una coma , la cual añade automáticamente un espacio delante del nombre de la variable o, alternativamente, se puede emplear el signo + con una variable que sea de tipo string.

nota = "10"
print("Tu nota es un " + nota)

En Java la función para imprimir strings es System.out.print(). Alternativamente, también se puede utilizar la función System.out.println(), la cual además de imprimir pone el cursor en la siguiente línea. Para concatenar texto se utiliza el signo + y la variable que se concatena no ha de ser necesariamente de tipo string.

int nota = 10;
System.out.println("Tu nota es un " + nota);

Variables

Como hemos visto en ejemplos anteriores, las variables en Python no requieren especificar su tipo de dato al declalarlas, pero sí que tenemos que asignarles un valor inicial. Además, una variable puede cambiar su tipo durante la ejecución del programa. También se pueden declarar multiples variables con el mismo valor en una sola línea usando el signo igual =, o con distintos valores separándolas con mediante comas ,.

# Variable que implícitamente es de tipo string
a = "uno"
# Declaración de tres variables con el mismo valor en una sola línea
a = b = c = 1
# Declaración de tres variables con valores distintos en una sola línea
uno, dos, tres = 1, 2, 3

En Java las variables se deben declarar de antemano y especificar su tipo al hacerlo, pero no es necesario asignarles un valor inicial. Una variable puede cambiar de valor siempre y cuando el nuevo valor sea del mismo tipo, pero si añadimos la palabra final al declararla entonces siempre tendrá el valor que le hayamos asignado. También se pueden declarar muchas variables en una misma línea separándolas con comas ,.

// Variable declarada pero no inicailizada
double nota;
// Variable que siempre tendrá el mismo valor
final int elementos = 10; 
// Declaración e inicialización de tres variables en una sola línea
int uno = 1, dos = 2, tres = 3;

Operadores

Python tiene muchos tipos de operadores. Entre ellos: operadores aritméticos (+, -, *, /, etc.), operadores de asignación (=, +=, -=, etc.), operadores de comparación (==, <, <=, etc.), operadores lógicos (and, or, not), operadores de identidad (is, is not), operadores de pertenencia (in, not in), y operadores a nivel de bits (^, |, etc.). Un operador que pueden encontrar a faltar programadores que vengan de otros lenguajes es el operador de autoincremento (++), muy utilizado para incrementar contadores y que en Python se realiza del siguiente modo: n += 1.

print("Operador de comparación:", 1 < 2)
print("Operador de identidad:", 2 is "2")
print("Operador de pertenencia:", 3 in [1, 2, 3])

Muchos de los operadores de Java son idénticos a los de Python. Además, Java incluye los operadores de autoincremento y autodecremento, pero no tiene operadores de identidad ni de pertenencia. Por otro lado, para los operadores lógicos and, or, not se utilizan respectivamente los símbolos &&, ||, !.

int n = 0;
System.out.println("Operador de autoincremento: " + (++n));
System.out.println("Operador de compraración: " + (1 < 2));
System.out.println("Operador lógico: " + (2 < 3 && 4 < 5));

Strings

Los strings en Python se pueden declarar entre comillas dobles ("") o entre comillas simples (''). Además, un string con comillas dobles acepta comillas simples en su interior y viceversa. También existe la posibilidad de crear strings multilínea con comillas triples. Por otro lado, el acceso a los caracteres individuales de un string se realiza del mismo modo que en una lista. Es decir, indicando entre corchetes el índice del carácter en cuestión. Igualmente, los strings se pueden iterar en un bucle for como una lista. En Python los strings son inmutables y tienen muchos métodos que ayudan a modificarlos (convertir el texto a mayúsculas, eliminar espacios en blanco, etc.). Una particularidad en Python es que se puede imprimir directamente un número sin necesidad de hacer un casting a tipo string.

print("Ella dijo: '¡Sí quiero!'")
print("Esto es un string"[0])
print("este texto se imprime en mayúsculas".upper())
print(1, "es un número")

En Java los strings sólo se pueden declarar utilizando comillas dobles. Las comillas simples también se utilizan, pero en este caso para declarar datos de tipo char, los cuales representan un carácter aislado. En Java los strings también son inmutables, aunque existe la posibilidad de hacerlos mutables utilizando las clases StringBuffer y StringBuilder. Un string se trata como si fuera un objeto con sus métodos para modificarlo. A diferencia de Python, en Java no existen los strings multilínea.

System.out.println("Esto es un String");
System.out.println('J');
StringBuffer hola = new StringBuffer("Hola, ");
System.out.println(hola);
hola.append("Java!");
System.out.println(hola);

Conversión de tipos (casting)

En programación la conversión de tipos (o casting en inglés) consiste en transformar una variable de un tipo de dato a otro. Por ejemplo, convertir un entero a número de coma flotante o a su representación en texto. En Python podemos comprobar el tipo de una variable mediante la función integrada type(). Los nombres que nos retorna type() para distintos tipos de datos son los que podemos utilizar para realizar conversión de tipos. Por ejemplo, si tenemos una variable n = 1, su tipo es int, pero podemos convertirla a tipo string con n = str(n).

n = 1
print(type(n))
print(type(str(n)))

En Java tenemos dos tipos de casting:

  • Implícito (o widening casting): es cuando se convierte un tipo de dato pequeño a otro más grande, por ejemplo de byte a short o de int a double. En este caso no hay que especificar nada, ya que el dato pequeño “cabe” dentro del grande.
  • Explícito (o narrowing casting): es el proceso inverso, es decir cuando se convierte un tipo de dato grande a otro más pequeño, por ejemplo de double a short o de int a byte. En este caso sí que hay que escribir código y puede producirse una pérdida de datos.
// Casting implícito
int n1 = 100;
long n2 = n1;
// Casting explícito
int n3 = 100;
short n4 = (short) n3;

Sentencias condicionales

En Python las sentencias condicionales incluyen bloques de código utilizando las palabras if, elif, y else. Como hemos visto anteriormente, el código a ejecutar en caso de que se cumpla la condición tiene que estar indentado. Además, el final de dicha condición se tiene que indicar con dos puntos:. Python también cuenta con los operadores ternarios, los cuales permiten ejecutar sentencias if-else en una sola línea de código.

# Sentencia if-else
num, msg = 6, ""
if num % 2 == 0:
    msg = "Par"
else:
    msg = "Impar"
print(msg)
# Operador ternario
msg = "Par" if num % 2 == 0 else "Impar"
print(msg)

En Java las sentencias condicionales se realizan con bloques de código if, else if, y else. Además, también incluye la sentencia switch-case. La condición a comprobar tiene que indicarse entre paréntesis, y el código a ejecutar en caso de que se cumpla la condición tiene que delimitarse mediante llaves. Java también dispone del operador ternario, aunque su sintaxis es distinta a la de Python tal y como vemos en el siguiente fragmento de código.

// Sentencia if-else
int num = 6;
String msg;
if (num % 2 == 0) {
    msg = "Par";
} else {
    msg = "Impar";
}
System.out.println(msg);
// Operador ternario
msg = num % 2 == 0 ? "Par" : "Impar";
System.out.println(msg);

Bucles

En Python se pueden realizar iteraciones mediante los bucles for y while. Como ya explicamos en un post anterior, los bucles for en Python no requieren especificar una variable de control ya que se itera sobre una colección de objetos. Una particularidad de Python es que el bucle for puede contener una sentencia else, la cual se ejecuta al finalizar el bucle siempre y cuando dentro del bucle no se haya activado ninguna sentencia break. Por otro lado, los bucles while en Python se ejecutan mientras la condición testeada sea verdadera. La variable de control se tiene que inicializar antes de entrar en el bucle y se incrementa (o decrementa) dentro del mismo.

for x in range(3):
    if x == 5:
        print("Encontrado!")
        break
else:
    print("5 no está dentro del loop!")

En Java, además de los bucles for y while, también tenemos el bucle do while. Los bucles while y do while son muy similares entre si. Su diferencia radica en que en el do while la condición que determina si se ejecuta el bucle se comprueba después del mismo y esto garantiza que la iteración se ejecuta por lo menos una vez. Por otro lado, los bucles for se realizan mediante una variable de control que determina el número de iteraciones a realizar. Sin embargo, Java también dispone del bucle for each, el cual es equivalente al for en Python.

// Bucle for
for (int i = 0; i < 4; i++) {
    System.out.println(i);
}
// Bucle for-each
int[] array = {0, 1, 2, 3};
for (int num : array) {
    System.out.println(num);
}

Funciones y métodos

Python tiene una serie de funciones integradas que nos facilitan la vida como programador, y que hemos tratado en otro post en Programa en Python. Por otro, las funciones definidas por el usuario tienen las siguientes particularidades:

  • Se declaran con la palabra clave def seguida del nombre de la función, sus argumentos entre paréntesis (si los tiene) y dos puntos :.
  • No se especifica el tipo del objeto retornado.
  • Los argumentos pueden ser posicionales, donde importa el orden en el cual se pasan los argumentos a la función, o de palabra clave, donde el orden no es importante ya que los argumentos quedan especificados mediante dichas palabras clave.
  • Si la función no está implementada, se puede usar una sentencia pass para evitar errores al llamarla.
  • Si la función no tiene una sentencia return, retorna por defecto un objeto NoneType.
# Función con argumentos posicionales
def suma(a, b):
    return a + b
# Llamada a la función suma
resultado = suma(1, 2)
# Función con argumentos de palabra clave
def multiplicacion(a=0, b=0):
    return a * b
# Llamada a la función multiplicación
resultado = multiplicacion(b=2, a=3)

Cuando declaramos un método en Java, tenemos que indicar obligatoriamente el tipo retornado, el nombre de la función, un par de paréntesis (), y un cuerpo entre llaves {}. Pero existen un total de seis parámetros para especificar un método, que van en el siguiente orden:

  • El modificador, que puede ser public, private, etc. y si el método es estático (con static) o no.
  • El tipo retornado, o void si el método no retorna nada.
  • El nombre del método.
  • Un listado de los parámetros del método separados por comas y encerrados entre paréntesis. Además, hay que especificar el tipo de cada parámetro.
  • Un listado de las excepciones que puede lanzar el método.
  • El cuerpo del método delimitado con llaves {}.

A parte, hay algunas consideraciones más en cuanto a los métodos en Java:

  • El valor retornado tiene que ser del tipo que se ha declarado en la firma del método.
  • Los argumentos se pasan en el mismo orden en que se han especificado sus respectivos parámetros.
  • Si un método es estático se puede llamar sin necesidad de instanciar un objeto.
public int suma(int a, int b) {
    return a + b;     
}

Manejo de excepciones

El manejo de excepciones consiste en tratar los posibles errores que se puedan producir durante la ejecución del código, para así evitar que el programa termine de forma inesperada. En Python cuando un bloque de código es susceptible de producir un error, se coloca en un bloque try, y cada una de las posibles excepciones se gestiona en un bloque except. Adicionalmente podemos definir un bloque finally para código que se tenga que ejecutar tanto si se produce una excepción como si no. Como programadores también podemos lanzar excepciones mediante la sentencia raise.

a, b = 1, 0
try:
    division = a / b
except ZeroDivisionError:
    print("Error al intentar dividir por cero!")

En Java las excepciones se manejan con bloques de código try ... catch. El bloque try, como en Python, contiene el código susceptible de producir una excepción. Dichas excepciones se pueden tratar en bloques catch, a un bloque por excepción ordenadas de más específica a más genérica para cubrir todos los posibles casos. También se puede añadir un bloque opcional finally, el cual se ejecuta siempre al final y está destinado a cerrar recursos como, por ejemplo, la conexión a una base de datos. Las excepciones se lanzan mediante la sentencia throws, la cual, como hemos visto anteriormente, también se debe utilizar en la signatura del método para especificar un listado de las posibles excepciones que lanza el mismo.

int a = 1, b = 0;
try {
    int division = a / b;
} catch (ArithmeticException e) {
    System.out.println("Error al intentar dividir por cero!");
}

Conclusiones

En este artículo hemos visto una comparación a fondo entre Python y Java, y más en particular como difieren ambos lenguajes de programación en un total de doce aspectos de su sintaxis. Si bien podría haber comparado muchos más aspectos, espero que el nivel de profundidad alcanzado te ofrezca una visión general de ambos lenguajes.

La popularidad de Python y Java hace que ambos lenguajes de programación tengan una amplia comunidad de desarrolladores y que sea fácil encontrar información en internet. Esto es especialmente importante para desarrolladores menos experimentados ya que al poder resolver sus dudas es más probable que no lo abandonen y sigan progresando.

No podemos concluir que uno sea mejor que el otro, ya que ambos tienen sus pros y sus contras. En líneas generales una persona sin conocimientos de programación encontrará Python mucho más fácil de aprender que Java. Sin embargo, Java es más eficiente al ejecutarse y menos propenso a errores ya que se trata de un lenguaje de programación de tipado estático.

En cualquier caso, una vez hemos aprendido bien un lenguaje de programación el siguiente será más fácil de aprender. Por tanto, a la hora de escoger uno para empezar a adentrarse en el mundo de la programación es importante que sepas qué tipo de aplicaciones quieres hacer en el futuro.

Foto del autor

Albert Brugués

Soy doctor en informática médica y un apasionado de la tecnología y las nuevas oportunidades que brinda. Más en particular me encanta la inteligencia artificial y el desarrollo web. En este blog pretendo compartir los conocimientos de Python que he ido adquiriendo a lo largo de los años.

Deja un comentario