Bienvenidos a otro capítulo de este Curso Gratis de Java para Hackers – Tipos de Variables de Java. Comparte este articulo y síguenos para recibir más capítulos, guías y cursos gratis.

Este curso está en constante actualización. Tendrá revisiones y actualizaciones anuales y correcciones y mejoras mensuales. Este curso está en un ciclo de crecimiento y mejora constante, agradecemos su apoyo difundiendo, compartiendo, comentando o simplemente leyéndolo.

¿Te gustaría enterarte de cuando lanzamos descuentos y nuevos cursos?

Tipos de variables de Java

Los siguientes son los tres tipos de variables Java:

  • variables locales
  • Variables de instancia
  • Clase/variables estáticas

Variables locales de Java

Las variables que no se pueden definir con la palabra clave “estática” se denominan variables locales en Java. Se declaran dentro del cuerpo del método y se usan sólo dentro de ese método, mientras que otros métodos de una clase no saben que la variable existe. 

  • Las variables locales se declaran en métodos , constructores o bloques.
  • Las variables locales se crean cuando se ingresa el método, constructor o bloque y la variable se destruirá una vez que salga del método, constructor o bloque.
  • Los modificadores de acceso no se pueden utilizar para variables locales.
  • Las variables locales solo son visibles dentro del método, constructor o bloque declarado.
  • Las variables locales se implementan internamente a nivel de pila.
  • No existe un valor predeterminado para las variables locales, por lo que las variables locales deben declararse y asignarse un valor inicial antes del primer uso.

Ejemplo 1: alcance local de la variable con inicialización

Aquí, la edad es una variable local. Esto se define dentro del método pupAge() y su alcance se limita únicamente a este método.

public class Test {

   public void pupAge() {

      int age = 0;

      age = age + 7;

      System.out.println("Puppy age is : " + age);

   }

   public static void main(String args[]) {

      Test test = new Test();

      test.pupAge();

   }

}

Producción

Puppy age is: 7

Ejemplo 2: alcance local de la variable sin inicialización

El siguiente ejemplo usa age sin inicializarlo, por lo que daría un error al momento de la compilación.

public class Test {

   public void pupAge() {

      int age;

      age = age + 7;

      System.out.println("Puppy age is : " + age);

   }

   public static void main(String args[]) {

      Test test = new Test();

      test.pupAge();

   }

}

Producción

Test.java:4:variable number might not have been initialized
age = age + 7;
         ^
1 error

Ejemplo 3 de variable local en Java

public class LocalVariableExample {
    public static void main(String[] args) {

int x = 5; // Local variable declaration and initialization
        System.out.println("The value of x is: " + x);

// Updating the value of x
        x = 10;
        System.out.println("The updated value of x is: " + x);

// Using a local variable in a loop
        for (int i = 0; i < 5; i++) {
            System.out.println("The value of i is: " + i);
        }
        // Uncommenting the line below will result in a compile-time error
        // System.out.println("The value of i outside the loop is: " + i);
    }
}

En el ejemplo, declaramos una variable local llamada x de tipo int dentro del método principal . Lo inicializamos con el valor 5 y luego imprimimos su valor en la consola. Posteriormente, actualizamos el valor de x a 10 e imprimimos el valor actualizado.

Además, mostramos el uso de una variable local i dentro de un bucle for . La variable i se declara dentro del alcance del bucle y se utiliza para controlar la iteración del bucle. Solo se puede acceder a él dentro del bloque de bucle y no se puede acceder a él fuera de él.

Si descomentas la última línea, se producirá un error porque i es una variable local limitada al alcance del bucle for y no se permite intentar acceder a ella fuera del bucle.

A continuación se muestra la implementación del enfoque anterior:

// Java Program to implement

// Local Variables
import java.io.*;

class Laprovittera {

    public static void main(String[] args)

    {

        // Declared a Local Variable

        int var = 10;

        // This variable is local to this main method only

        System.out.println("Local Variable: " + var);

    }

}

Producción

Local Variable: 10

Ejemplo :

package a;
public class LocalVariable {

    public static void main(String[] args)

    {

        // x is a local variable

        int x = 10;

        // message is also a local

        // variable

        String message = "Hello, world!";

        System.out.println("x = " + x);

        System.out.println("message = " + message);

        if (x > 5) {

            // result is a

            // local variable

            String result = "x is greater than 5";

            System.out.println(result);

        }

        // Uncommenting the line below will result in a

        // compile-time error System.out.println(result);

        for (int i = 0; i < 3; i++) {

            String loopMessage

                = "Iteration "

                  + i; // loopMessage is a local variable

            System.out.println(loopMessage);

        }

        // Uncommenting the line below will result in a

        // compile-time error

        // System.out.println(loopMessage);

    }

}

Producción :

message = Hello, world!

x is greater than 5

Iteration 0

Iteration 1

Iteration 2

Variables de instancia de Java

Las variables de instancia se declaran dentro de una clase pero fuera de un método. Se definen sin la palabra clave “estática”. Como su valor es específico de la instancia y no se comparten entre instancias, se denominan variables de instancia. 

  • Las variables de instancia se declaran en una clase , pero fuera de un método, constructor o cualquier bloque.
  • Cuando se asigna un espacio para un objeto en el montón, se crea una ranura para cada valor de variable de instancia.
  • Las variables de instancia se crean cuando se crea un objeto con el uso de la palabra clave ‘nuevo’ y se destruyen cuando se destruye el objeto.
  • Las variables de instancia contienen valores a los que debe hacer referencia más de un método, constructor o bloque, o partes esenciales del estado de un objeto que deben estar presentes en toda la clase.
  • Las variables de instancia se pueden declarar a nivel de clase antes o después de su uso.
  • Se pueden dar modificadores de acceso, por ejemplo, variables.
  • Las variables de instancia son visibles para todos los métodos, constructores y bloques de la clase. Normalmente, se recomienda hacer que estas variables sean privadas (nivel de acceso). Sin embargo, se puede dar visibilidad a las subclases de estas variables con el uso de modificadores de acceso.
  • Las variables de instancia tienen valores predeterminados. Para los números, el valor predeterminado es 0, para los booleanos es falso y para las referencias a objetos es nulo. Los valores se pueden asignar durante la declaración o dentro del constructor.
  • Se puede acceder a las variables de instancia directamente llamando al nombre de la variable dentro de la clase. Sin embargo, dentro de los métodos estáticos (cuando las variables de instancia tienen accesibilidad), se deben llamar usando el nombre completo. ReferenciaDeObjeto.NombreVariable .

Ejemplo de variables de instancia de Java

import java.io.*;

public class Employee {

   // this instance variable is visible for any child class.

   public String name;

   // salary  variable is visible in Employee class only.

   private double salary;

   // The name variable is assigned in the constructor.

   public Employee (String empName) {

      name = empName;

   }

   // The salary variable is assigned a value.

   public void setSalary(double empSal) {

      salary = empSal;

   }

   // This method prints the employee details.

   public void printEmp() {

      System.out.println("name  : " + name );

      System.out.println("salary :" + salary);

   }

   public static void main(String args[]) {

      Employee empOne = new Employee("Ransika");

      empOne.setSalary(1000);

      empOne.printEmp();

   }

}

Producción

name  : Ransika
salary :1000.0

Ejemplo de variable de instancia en Java:

public class InstanceVariableExample {
    private int count; // Instance variable
    public void increment() {
        count++; // Accessing and modifying the instance variable
    }
    public void displayCount() {
        System.out.println("The count is: " + count); // Accessing the instance variable
    }
    public static void main(String[] args) {
        InstanceVariableExample obj1 = new InstanceVariableExample();
        InstanceVariableExample obj2 = new InstanceVariableExample();
        obj1.increment();
        obj1.displayCount(); // Output: The count is: 1
        obj2.increment();
        obj2.displayCount(); // Output: The count is: 1
    }
}

En el ejemplo, definimos una clase llamada InstanceVariableExample . Dentro de esta clase, declaramos una variable de instancia llamada count de tipo int . La variable de recuento no es estática, lo que significa que está asociada con cada instancia de la clase en lugar de compartirse entre todas las instancias.

Dentro de la clase, tenemos dos métodos: increment() y displayCount() . El método increment() incrementa el valor de la variable de instancia de recuento en uno. El método displayCount() simplemente imprime el valor de la variable de instancia de recuento.

En el método main(), creamos dos objetos ( obj1 y obj2 ) de la clase InstanceVariableExample . Cada objeto tiene su propia copia del recuento de variables de instancia. Llamamos al método increment() en ambos objetos y luego llamamos al método displayCount() para imprimir el valor de recuento para cada objeto.

Como resultado, vemos que cada objeto mantiene su propia copia separada del recuento de variables de instancia. Cuando incrementamos el recuento en un objeto, no afecta el valor del recuento en el otro objeto.

A continuación se muestra la implementación del enfoque anterior:

// Java Program to demonstrate

// Instance Variables

import java.io.*;

class Laprovittera {

    // Declared Instance Variable

    public String hacker;

    public int i;

    public Integer I;

    public Laprovittera()

    {

        // Default Constructor

        // initializing Instance Variable

        this.hacker = "Shubham Jain";

    }

    // Main Method

    public static void main(String[] args)

    {

        // Object Creation

        Laprovittera name = new Laprovittera();

        // Displaying O/P

        System.out.println("Hacker name is: " + name.hacker);

        System.out.println("Default value for int is "

                           + name.i);

        // toString() called internally

        System.out.println("Default value for Integer is "

                           + name.I);

    }

}

Producción

Hacker name is: Shubham Jain
Default value for int is 0
Default value for Integer is null

Clase Java/Variables estáticas

La variable estática, o una variable de clase en Java, se declara como estática y se inicializa solo una vez al comienzo de la ejecución del programa. Deben inicializarse antes de inicializar cualquier variable de instancia. Puede compartir una única copia de estas variables y compartirla con las instancias de la clase. 

Veamos algunos puntos:

  • Las variables de clase, también conocidas como variables estáticas, se declaran con la palabra clave estática en una clase, pero fuera de un método, constructor o bloque.
  • Sólo habría una copia de cada variable de clase por clase, independientemente de cuántos objetos se creen a partir de ella.
  • Las variables estáticas rara vez se utilizan aparte de declararse como constantes. Las constantes son variables que se declaran como públicas/privadas, finales y estáticas. Las variables constantes nunca cambian de su valor inicial.
  • Las variables estáticas se almacenan en la memoria estática. Es raro utilizar variables estáticas distintas de las declaradas finales y utilizadas como constantes públicas o privadas.
  • Las variables estáticas se crean cuando se inicia el programa y se destruyen cuando el programa se detiene.
  • La visibilidad es similar a las variables de instancia. Sin embargo, la mayoría de las variables estáticas se declaran públicas ya que deben estar disponibles para los usuarios de la clase.
  • Los valores predeterminados son los mismos que los de las variables de instancia. Para los números, el valor predeterminado es 0; para los booleanos, es falso; y para referencias a objetos, es nulo. Los valores se pueden asignar durante la declaración o dentro del constructor. Además, se pueden asignar valores en bloques inicializadores estáticos especiales.
  • Se puede acceder a las variables estáticas llamando con el nombre de clase ClassName.VariableName .
  • Al declarar variables de clase como públicas estáticas finales, los nombres de las variables (constantes) están todos en mayúsculas. Si las variables estáticas no son públicas y finales, la sintaxis de denominación es la misma que la de las variables locales y de instancia.

Ejemplo de clase Java/variables estáticas

import java.io.*;

public class Employee {

   // salary  variable is a private static variable

   private static double salary;

   // DEPARTMENT is a constant

   public static final String DEPARTMENT = "Development ";

   public static void main(String args[]) {

      salary = 1000;

      System.out.println(DEPARTMENT + "average salary:" + salary);

   }

}

Producción

Development average salary:1000

Nota : si se accede a las variables desde una clase externa, se debe acceder a la constante como Empleado.DEPARTAMENTO

Ejemplo de variable estática en Java

public class StaticVariableExample {
    private static int count; // Static variable
    public StaticVariableExample() {
        count++; // Incrementing the static variable in the constructor
    }
    public void displayCount() {
        System.out.println("The count is: " + count); // Accessing the static variable
    }
    public static void main(String[] args) {
        StaticVariableExample obj1 = new StaticVariableExample();
        obj1.displayCount(); // Output: The count is: 1
        StaticVariableExample obj2 = new StaticVariableExample();
        obj2.displayCount(); // Output: The count is: 2
    }
}

Aquí, definimos una clase llamada StaticVariableExample . Dentro de esta clase, declaramos una variable estática llamada count de tipo int . La variable count se declara con la palabra clave estática, lo que significa que está asociada con la clase misma en lugar de instancias individuales (objetos) de la clase. Todos los objetos de la clase comparten la misma copia de la variable estática.

También tenemos un constructor en la clase, que se invoca cuando se crea un objeto. En el constructor, incrementamos el valor de la variable estática count en uno.

El método displayCount() simplemente imprime el valor del recuento de la variable estática.

En el método main() , creamos dos objetos ( obj1 y obj2 ) de la clase StaticVariableExample . Cuando creamos cada objeto, se llama al constructor y se incrementa el recuento de variables estáticas.

Finalmente, llamamos al método displayCount() en ambos objetos, que imprime el valor de recuento para cada objeto. Dado que la variable estática se comparte entre todos los objetos, el recuento aumenta con cada creación de objeto.

Como resultado, vemos que ambos objetos tienen acceso y modifican la misma variable estática, y cualquier cambio realizado en la variable estática se refleja en todas las instancias de la clase.

A continuación se muestra la implementación del enfoque anterior:

// Java Program to demonstrate

// Static variables

import java.io.*;

class laprovittera {

    // Declared static variable

    public static String hacker = "Shubham Jain";

    public static void main(String[] args)

    {

        // geek variable can be accessed without object

        // creation Displaying O/P laprovittera.hacker --> using the

        // static variable

        System.out.println("Hacker Name is : " + laprovittera.hacker);

        // static int c=0;

        // above line,when uncommented,

        // will throw an error as static variables cannot be

        // declared locally.

    }

}

Producción

Hacker Name is : Shubham Jain

Diferencias entre las variables de instancia y las variables estáticas

Ahora analicemos las diferencias entre las variables de instancia y las variables estáticas:

  • Cada objeto tendrá su propia copia de una variable de instancia, mientras que solo podemos tener una copia de una variable estática por clase, independientemente de cuántos objetos creemos. Por tanto, las variables estáticas son buenas para la gestión de la memoria .
  • Los cambios realizados en una variable de instancia utilizando un objeto no se reflejarán en otros objetos ya que cada objeto tiene su propia copia de la variable de instancia. En el caso de una variable estática, los cambios se reflejarán en otros objetos ya que las variables estáticas son comunes a todos los objetos de una clase.
  • Podemos acceder a variables de instancia a través de referencias de objetos, y se puede acceder a variables estáticas directamente usando el nombre de la clase .
  • Las variables de instancia se crean cuando se crea un objeto con el uso de la palabra clave ‘nuevo’ y se destruyen cuando se destruye el objeto. Las variables estáticas se crean cuando se inicia el programa y se destruyen cuando el programa se detiene.

Sintaxis: variables estáticas y de instancia

class laprovittera

{

    // Static variable

    static int a;

    // Instance variable

    int b;       

}

Conclusión

Los puntos importantes a recordar en los artículos se mencionan a continuación:

  • Las variables en Java son un contenedor de datos que guarda los valores de los datos durante la ejecución del programa Java.
  • Hay tres tipos de variables en Java: variables locales, variables estáticas y variables de instancia.


Alcance de las variables en Java

Última actualización: 28 de junio de 2021

El alcance de una variable es la parte del programa donde se puede acceder a la variable. Al igual que C/C++, en Java, todos los identificadores tienen un alcance léxico (o estático), es decir, el alcance de una variable se puede determinar en el momento de la compilación y es independiente de la pila de llamadas a funciones. 

Los programas Java están organizados en forma de clases. Cada clase es parte de algún paquete. Las reglas de alcance de Java se pueden cubrir en las siguientes categorías.

Variables miembro (alcance de nivel de clase)

Estas variables deben declararse dentro de la clase (fuera de cualquier función). Se puede acceder a ellos directamente desde cualquier lugar de la clase. Echemos un vistazo a un ejemplo: 

public class Test
{
    // All variables defined directly inside a class
    // are member variables
    int a;
    private String b;
    void method1() {....}
    int method2() {....}
    char c;
}
  • Podemos declarar variables de clase en cualquier lugar de la clase, pero fuera de los métodos.
  • El acceso especificado a las variables miembro no afecta su alcance dentro de una clase.
  • Se puede acceder a las variables miembro fuera de una clase con las siguientes reglas

Modifier      Package  Subclass  World

public          Yes      Yes     Yes

protected       Yes      Yes     No

Default (no
modifier)       Yes       No     No

private         No        No     No

Variables locales (alcance del nivel del método)

Las variables declaradas dentro de un método tienen alcance a nivel de método y no se puede acceder a ellas fuera del método. 

public class Test
{
    void method1()
    {
       // Local variable (Method level scope)
       int x;
    }
}

Nota: las variables locales no existen una vez finalizada la ejecución del método. 

Aquí hay otro ejemplo del alcance del método, excepto que esta vez la variable se pasó como parámetro al método: 

class Test
{
    private int x;
    public void setX(int x)
    {
        this.x = x;
    }
}

El código anterior utiliza esta palabra clave para diferenciar entre las variables locales y de clase.

Como ejercicio, prediga el resultado del siguiente programa Java.  

public class Test

{

    static int x = 11;

    private int y = 33;

    public void method1(int x)

    {

        Test t = new Test();

        this.x = 22;

        y = 44;

        System.out.println("Test.x: " + Test.x);

        System.out.println("t.x: " + t.x);

        System.out.println("t.y: " + t.y);

        System.out.println("y: " + y);

    }

    public static void main(String args[])

    {

        Test t = new Test();

        t.method1(5);

    }

}

Producción: 

Test.x: 22
t.x: 22
t.y: 33
y: 44

Variables de bucle (alcance del bloque) 

Una variable declarada dentro del par de corchetes “{” y “}” en un método tiene alcance solo entre corchetes.

public class Test

{

    public static void main(String args[])

    {

        {

            // The variable x has scope within

            // brackets

            int x = 10;

            System.out.println(x);

        }

        // Uncommenting below line would produce

        // error since variable x is out of scope.

        // System.out.println(x);

    }

}

Producción: 

10

Como otro ejemplo, considere el siguiente programa con un bucle for. 

class Test

{

    public static void main(String args[])

    {

        for (int x = 0; x < 4; x++)

        {

            System.out.println(x);

        }

        // Will produce error

        System.out.println(x);

    }

}

Producción: 

11: error: no se puede encontrar el símbolo
        System.out.println(x);     

La forma correcta de hacerlo arriba es, 

// Above program after correcting the error

class Test

{

    public static void main(String args[])

    {

        int x;

        for (x = 0; x < 4; x++)

        {

            System.out.println(x);

        }

       System.out.println(x);

    }

}

Producción: 

0
1
2
3
4

Veamos un ejemplo complicado de alcance de bucle. Predecir el resultado del siguiente programa. Puede que te sorprendas si eres un programador habitual de C/C++. 

class Test

{

    public static void main(String args[])

    {

        int a = 5;

        for (int a = 0; a < 5; a++)

        {

            System.out.println(a);

        }

    }

}

Producción :

6: error: variable a is already defined in method go(int)
       for (int a = 0; a < 5; a++)      
                ^
1 error

Nota: – En C++, se ejecutará. Pero en Java es un error porque en Java, el nombre de la variable del bucle interno y externo debe ser diferente.

Funciona un programa similar en C++.

Como ejercicio, prediga el resultado del siguiente programa Java. 

class Test

{

    public static void main(String args[])

    {

        {

            int x = 5;

            {

                int x = 10;

                System.out.println(x);

            }

        }

    }

}

P. A partir del conocimiento anterior, indique si el siguiente código se ejecutará o no.

class Test {

    public static void main(String args[])

    {

        for (int i = 1; i <= 10; i++) {

            System.out.println(i);

        }

        int i = 20;

        System.out.println(i);

    }

}

Producción : 

1
2
3
4
5
6
7
8
9
10
20

¡Sí, funcionará! 

Vea el programa con atención, el bucle interno terminará antes de que se declare la variable del bucle externo, por lo que la variable del bucle interno se destruye primero y luego se crea la nueva variable con el mismo nombre.

Algunos puntos importantes sobre el alcance de las variables en Java:  

  • En general, un conjunto de llaves { } define un alcance.
  • En Java generalmente podemos acceder a una variable siempre que esté definida dentro del mismo conjunto de corchetes que el código que estamos escribiendo o dentro de cualquier llave dentro de las llaves donde se definió la variable.
  • Cualquier variable definida en una clase fuera de cualquier método puede ser utilizada por todos los métodos miembros.
  • Cuando un método tiene la misma variable local que un miembro, la palabra clave “esta” se puede usar para hacer referencia a la variable de clase actual.
  • Para que una variable se lea después de la terminación de un bucle, debe declararse antes del cuerpo del bucle.

No te detengas, sigue avanzando

Aquí tienes un propósito para este 2024 que debes considerar seriamente: si has querido mejorar tus habilidades en hacking, Ciberseguridad y programación ahora es definitivamente el momento de dar el siguiente paso. ¡Desarrolla tus habilidades aprovechando nuestros cursos a un precio increíble y avanza en tu carrera! El mundo necesita más hackers…

Universidad Hacking. Todo en Ciberseguridad. Curso Completo

Aprende Hacking Ético y Ciberseguridad sin necesitar conocimientos Previos. Practica Hacking Ético y Ciberseguridad aquí

Calificación: 4,6 de 5 (2.877 calificaciones) 15.284 estudiantes Creado por Alvaro Chirou • 1.800.000+ Enrollments Worldwide

Lo que aprenderás

  • Seguridad informática
  • Hacking Ético en profundidad
  • Redes
  • Programación (Python) (Hacking con Python)
  • Análisis de Malware con laboratorios, practicas y ejecución de Malware para que veas su comportamiento.
  • Cómo reforzar tu Privacidad y Anonimato
  • Uso avanzado de Metasploit
  • Top 10 de Owasp Web, Top 10 de Owasp mobile y Top 10 de Owasp API
  • Seguridad informática para empresas
  • Kali linux de 0 a 100, Veremos su suite de herramientas de hacking y como explotar fallos en sistemas.
  • Termux y como hackear desde el celular
  • Seguridad informática server/web, profundizaremos en WordPress
  • Análisis de trafico en Wireshark
  • Y mucho, pero mucho más

¿Esto que significa?

Hoy más que nunca, se necesitan personas capacitadas en este rubro para trabajar.

Por esa razón cree esta formación profesional para compartirte mis conocimientos y experiencia en la materia y puedas iniciar en este mundo del Hacking Ético y Ciberseguridad.

Te voy a estar acompañando en el proceso de aprendizaje, donde si estas empezando desde 0, sin conocimientos previos, no es un impedimento ya que iniciaremos como si no supieras nada de la materia.

Si sos una persona con conocimientos, podrás iniciar directamente en el nivel más avanzado o en el que tu elijas.

Como en todos mis cursos en udemy, tendrás muchísima practica para que materialices lo que vas aprendiendo.

Empieza a aprender ya mismo!

Aprende con nuestros más de 100 cursos que tenemos disponibles para vos

No solo te enseñamos, tambien te guíamos para que puedas conseguir trabajo como desarrollador y hacker…

¿Te gustaría enterarte de cuando lanzamos descuentos y nuevos cursos?

Sobre los autores

Álvaro Chirou

Yo soy Álvaro Chirou, tengo más de 20 Años de experiencia trabajando en Tecnología, eh dado disertaciones en eventos internacionales como OWASP, tengo más de 1.800.000 estudiantes en Udemy y 100 formaciones profesionales impartidas en la misma. Puedes serguirme en mis redes:

Laprovittera Carlos

Soy Laprovittera Carlos. Con más de 20 años de experiencia en IT brindo Educación y Consultoría en Seguridad de la Información para profesionales, bancos y empresas. Puedes saber más de mi y de mis servicios en mi sitio web: laprovittera.com y seguirme en mis redes:

¿Quieres iniciarte en hacking y ciberseguridad pero no sabes por dónde empezar? Inicia leyendo nuestra guia gratuita: https://achirou.com/como-iniciarse-en-ciberseguridad-y-hacking-en-2024/ que te lleva de 0 a 100. Desde los fundamentos más básicos, pasando por cursos, recursos y certificaciones hasta cómo obtener tu primer empleo.

SIGUE APRENDIENDO GRATIS CON NUESTRAS GUIAS

Cómo Iniciarse en Hacking y Ciberseguridad en 2024

Curso Gratis de Programación

Curso Gratis Linux – Capitulo 1 – Introducción a Linux

Curso Gratis de Redes – Capitulo 1 – Tipos de redes y servicios

Como iniciarse en TRY HACK ME – Complete Beginner #1

OSINT #1 Más de 200 Search Tools