Tartalomjegyzék

< Java

Java nyelv jellemzők

JVM utasítások

Néhol Java Virtual Machine Language néven említik, de ez nem terjedt el.

Java alacsony szintű nyelv vagy bájtkód. Az operációs rendszeren közvetlenül nem futtatható kód. A Java Runtime Environment fordítja futtatható kóddá.

A változók élettartalma

Példány változó

Egyed, példány, instance változó. Egy példányosított osztály egy változója. Az osztály tulajdonságainak vagy mezőinek is szokás nevezni.

A példányváltozót egy osztályban hozunk létre, de metóduson kívül.

Amikor helyet foglalunk egy objektumnak az osztály összes változója számára megtörténik a helyfoglalás a halomterületen. Hozzáférés-módosítókat használhatunk ezeken a változókon. A példányváltozók az osztály összes metódusa számára hozzáférhető. Ajánlott private elérésűként megadni.

A példányváltozóknak van kezdő értékük. Számok esetén ez 0, boolean esetén ez false, objektumhivatkozás null értéket vesz fel.

objektumHivatkozas.valtozoNev

Statikus változó

Statikus, osztály vagy static változó. Példányosítás nélkül használható változó. A változó helyett néha statikus mező, esetleg osztályváltozó néven is használjuk.

A static módosítóval hozzuk létre, osztályon belül, de metóduson kívül. A váltózóból mindig csak egy másolat jön létre. Általában állandóként szoktuk használni. Az állandót public/private, final és static módosítókkal szoktuk megadni.

A static változókat a statikus memóriaterületen tároljuk. Akkor jönnek létre, amikor elindul a program. A program befejezésével együtt megszűnnek.

Alapértelmezett értékei mint a példányváltozók.

Ha egy statikus tagot final-ként adunk meg, akkor a nevét nagybetűvel szokás írni.

Lokális változó

Egy metódusban – esetleg konstruktorban vagy blokkban – létrehozott változó. Csak az adott metódusban él, annak végrehajtása után már nem hivatkozhatunk a változóira. Maga a változó a memóriában is csak akkor jön létre amikor belépünk a metódusba. A lokális változót nem illetjük mező elnevezéssel. Hasonló szerepe van még a paraméterváltozóknak is.

A hozzáférés-módosítók nem alkalmazhatók. Mindig a veremben (stack) kerül lefoglalásra. Ha példányosítunk lokálisan egy osztályt, a változó szintén a veremben jön létre, de a hozzátartozó tagok, a halom (heap) terülten lesznek tárolva.

A lokális változóknak alapértelmezésként nem kapnak kezdőértéket, ezért az első felhasználás előtt elő kell készíteni azokat.

Paraméter változó

Emlékezzünk vissza, hogy a main metódus aláírása public static void main(String[] args). Az args a paraméterváltozó.

Változók élettartalma a gyakorlatban

Instance változók

class Szemely {
	String Nev;
	int Kor;	
}
 
class Valotozok {
	public static void main(String[] args) {
		Szemely Joska = new Szemely();
 
		Joska.nev = "Nagy József";
		Joska.kor = 25;
 
		System.out.println(Joska.Nev);
		System.out.println(Joska.Kor);		
	}
}

Static változók

class Szemely {
	static String nev;
	static int kor;	
}
 
class Valotozok {
	public static void main(String[] args) {
 
		Szemely.Nev = "Nagy József";
		Szemely.Kor = 25;
 
		System.out.println(Szemely.Nev);
		System.out.println(Szemely.Kor);		
	}
}

Local változó

class Valotozok {
	public static void main(String[] args) {
		String Nev;
                int Kor;
 
                Nev = "Nagy József";
		Kor = 25;
 
		System.out.println(Nev);
		System.out.println(Kor);		
	}
}

A csomagolóosztályokról

A csomagoló osztály típussal létrehozott változók az értéket példány vagy osztályváltozókban tárolják, és rendelkeznek metódusokkal. A primitív típusok nem rendelkeznek metódusokkal. A csomagolóosztály-típusokat bárhol használhatunk, de néhány helyen kötelező. Ilyenek a vermek (stack), vektorok (vector), object I/O, szerializáció, stb.

Program01.java
import java.util.Stack;
 
class Program01 {
    public static void main(String [] args) {
	Stack<Integer> verem = new Stack<Integer>();
 
	int a = 5;
 
	verem.push(a);
    }
}

Az int primitív típus itt nem használható például a Stack adatszerkezet használata esetén (lásd később): Stack<int> verem = new Stack<int>();.

A burkoló vagy csomagoló osztályokat angolul (wrapper [ˈræpə]).

Az instanceof operátor

Az operátorok fejezetben az instanceof operátort az Integer változóval mutattuk be, aminek nem sok értelme van, mert más típust nem is írhatunk az instanceof jobboldalára. Annál több értelme lehet ha egy általunk létrehozott osztályon vizsgáljuk, vagy annak egy származtatott változatán.

A következő példában megnézhetjük, hogy a joska objektum melyik osztályból lett származtatva:

Program01.java
class Dolgozo {
	String nev;
	int kor;
}
class Mernok extends Dolgozo {
	String diploma;
}
class Program01 {
	public static void main(String[] args) {
		Dolgozo joska = new Dolgozo();		
		System.out.println(joska instanceof Mernok);		
	}
}

Az Extra csomag

Sokan használják Angster Erzsébet által létrehozott Extra nevű csomagot, amely kényelmesebbé teszi a bekéréseket. Az extra csomag azonban nem a JDK részre, ne felejtsük el. Azt telepíteni kell vagy csak egyszerűen a használt programunk mellet létrehozni egy extra könyvtárat, majd abba menteni Console.java néven.

extra/Console.java
/*
* javalib könyvtár
* Csomag: extra
* Console.java
*
* Angster Erzsébet: OO tervezés és programozás, Java 1. kötet
* 2002.09.01.
*
* Beolvasás a konzolról:
*
* String readLine()
* String readLine(String str)
* char readChar()
* char readChar(String str)
* int readInt()
* int readInt(String str)
* int readLong()
* int readLong(String str)
* double readDouble()
* double readDouble(String str)
* void pressEnter()
*/
 
package extra;
import java.io.*;
 
public class Console
{
// Az osztályból nem lehet példányt létrehozni:
	private Console()
	{
	}
 
	/* Pufferező karakterfolyam, melynek forráshelye a konzol.
	* A readLine metódus használja.
	*/
	private static BufferedReader be =
	    new BufferedReader(new InputStreamReader(System.in));
 
// ---------------------------------------------------------
// String beolvasása sor végéig:
	public static String readLine()
	{
		String beString = "";
		try
		{
			beString = be.readLine();
		}
		catch (IOException e)
		{
		}
		return beString;
	}
 
// ---------------------------------------------------------
// String beolvasása sor végéig, előtte prompt:
	public static String readLine(String str)
	{
		System.out.print(str);
		return readLine();
	}
 
// ---------------------------------------------------------
// Karakter beolvasása:
	public static char readChar()
	{
		while(true)
		{
			try
			{
				return readLine().charAt(0);
			}
			catch(IndexOutOfBoundsException e)
			{
				System.out.println("Nem karakter! Ujra!");
			}
		}
	}
 
// ---------------------------------------------------------
// Karakter beolvasása, előtte prompt:
	public static char readChar(String str)
	{
		System.out.print(str);
		return readChar();
	}
 
// ---------------------------------------------------------
// Egész (int) beolvasása:
	public static int readInt()
	{
		while(true)
		{
			try
			{
				return Integer.parseInt(readLine().trim());
			}
			catch(NumberFormatException e)
			{
				System.out.println("Nem egesz! Ujra!");
			}
		}
	}
 
// ---------------------------------------------------------
// Egész (int) beolvasása, előtte prompt:
	public static int readInt(String str)
	{
		while(true)
		{
			System.out.print(str);
			try
			{
				return Integer.parseInt(readLine().trim());
			}
			catch(NumberFormatException e)
			{
				System.out.println("Nem egesz! Ujra!");
			}
		}
	}
 
// ---------------------------------------------------------
// Egész (long) beolvasása:
	public static long readLong()
	{
		while(true)
		{
			try
			{
				return Long.parseLong(readLine().trim());
			}
			catch(NumberFormatException e)
			{
				System.out.println("Nem egesz! Ujra!");
			}
		}
	}
 
// ---------------------------------------------------------
// Egész (long) beolvasása, előtte prompt:
	public static long readLong(String str)
	{
		while(true)
		{
			System.out.print(str);
			try
			{
				return Long.parseLong(readLine().trim());
			}
			catch(NumberFormatException e)
			{
				System.out.println("Nem egesz! Ujra!");
			}
		}
	}
 
// ---------------------------------------------------------
// Valós (double) beolvasása:
	public static double readDouble()
	{
		while(true)
		{
			try
			{
				return Double.parseDouble(readLine().trim());
			}
			catch(NumberFormatException e)
			{
				System.out.println("Nem valos! Ujra!");
			}
		}
	}
 
// ---------------------------------------------------------
// Valós (double) beolvasása, előtte prompt:
	public static double readDouble(String str)
	{
		while(true)
		{
			System.out.print(str);
			try
			{
				return Double.parseDouble(readLine().trim());
			}
			catch(NumberFormatException e)
			{
				System.out.println("Nem valos! Ujra!");
			}
		}
	}
 
// ---------------------------------------------------------
// Várás az ENTER lenyomására:
	public static void pressEnter()
	{
		System.out.print("<ENTER>");
		readLine();
	}
}

Várakozás egy billentyűnyomásra

Az alábbi példa bemutatja hogyan várakozhatunk egy billentyűlenyomásra. A „billentyűlenyomás” nem teljes kifejezés, mert csak az „Enter” billentyűt nyomhatjuk le.

Program01.java
import java.io.IOException;
import java.util.Scanner;
 
class Program01 {
    public static void main(String args[]) throws IOException {
        Scanner bevitel = new Scanner(System.in);
 
        System.out.print("Egész szám: ");
	int a = bevitel.nextInt();
 
	System.out.println(a);
 
        System.in.read();
     }
}
Program01
class Program01 {
	public static void main(String args[]) {
 
		System.out.println("A folytatashoz nyomjon egy Entert");
		System.console().readLine();
	}
}

Unicode karakterek kiíratása

Program01.java
class Program01 {
	private static void tabla2() {
		for(int i=0x0021;i<=0x01ff; i++)
			System.out.printf("| %x %c |", i, (char) i);
	}
	public static void main(String[] args) {
		tabla2();
	}
}

Ezek után képernyőre küldhető:

System.out.println("\u0171");
System.out.println((char)0x63A5);

Garbage Collector

A Java Garbage Collector vagy röviden csak GC, egy szemétgyűjtő. A nem használt objektumok számára lefoglalt memóriaterületet felszabadítja. A GC időnként lefut magától, ha kevés a memória vagy túl sok nem használt objektum van.

A GC futását kérhetjük a JVM-től a következő utasítással:

System.gc();

Ami persze nem ajánlott, bízzuk ezt a JVM-re. A GC-t a JVM magától futtatja, ha kevés a memória vagy sok a felhalmozodott objektum.

Van aki szerint a fokozott biztonsági igényű vezérlést nem szabad Java-ban írni, mert a GC is lefagyhat, előfordulhat hiba. A C nyelv esetén nekünk kell mindenről gondoskodni.

Több információ a memóriakezelésről:

VisualVM

VisualVM segítségével megnézhetjük hogyan használja egy Java program a gépet, a processzort, a memóriát, stb.

Linux alatt a telepítése egyszerű:

apt install visualvm

Indítása:

jvisualvm

A program maga egy Java alapú program, amely letölthető innen:

Változó hosszúságú argumentumok

A típus után, három darab ponttal jelezhetjük, hogy az adott típusból akár több is megadható. Az alábbi példában több double típust is megadhatunk a csinal() függvény hívásakor. Az eredmény egy kollekció lesz, amit bejárunk for() utasítással.

Program01.java
public class Program01 {
	public static void csinal(double... szamok) {
		for(double szam : szamok) {
			System.out.printf("%20f\n", szam);
		}
	}
	public static void main (String args[]) {
		csinal(4, 5);
	}
}

Ugyanez String típussal:

Program01.java
public class Program01 {
	public static void csinal(String... szavak) {
		for(String szo : szavak) {
			System.out.printf("%20s\n", szo);
		}
	}
	public static void main (String args[]) {
		csinal("alma", "szilva");
	}
}

Számliterálisok a Java SE 7-től

A Java SE 7 verzióban fejlesztették a számliterálisok megadási lehetőségeit.

A 102-őt korábban így adhattuk meg:

int x = Integer.parseInt("1100110", 2);

Ezen túl megadható így is:

int x = 0b1100110;
Program01.java
class Program01 {
	public static void main(String[] args) {
		int a = 0b1100110;		
		System.out.println(a);
 
		long b = 2_143_234L;
		System.out.printf("%d\n", b);
 
		int c = 0b0001_1100_0111_0011;
		System.out.println(c);
	}
}

Fok jel

W7 alatt a ° karakter nem jelenik meg a konzolos felületen. Ezért használjuk a következők valamelyikét:

System.out.println((char)345);
System.out.println("\u0159");

A 345 egy decimális szám. Ugyanaz a szám hexadecimálisan: 159.

A Java verzió kiíratása

Minden Java verzióval működik:

System.out.println(System.getProperty("java.specification.version"));

9-s verziótól:

System.out.println(System.getProperty("java.version"));