Java pro fyziky
Michal Voců
ÚVT UK
Obsah
Historie jazyka Java
- původně vyvíjen jako jazyk pro domácí spotřebiče (1990)
- po rozvoji Internetu a WWW (1993) jazyk pro programování na
Internetu - the network is the computer
- nyní stále častěji i jazyk pro psaní aplikací
- WWW prohlížeče - Jazilla, HotJava
- e-mailoví klienti - Grendel
- textové a tabulkové procesory, ...
- současná verze - Java 2 (JDK 1.2.2)
- navazující technologie:
- RMI - vzdálené volání metod (RMI over IIOP),
- CORBA - distribuované objektově orientované aplikace,
- JDBC - přístup k databázím,
- XML - zpracování dokumentů,
- JNDI - přístup k adresářovým službám (LDAP, ...),
- JNI API - přístup k nativním (C, C++, ...) funkcím.
Hlavní rysy
Obecná charakteristika
- jednoduchý - syntakticky podobný C/C++
- objektově-orientovaný
- distribuovaný - podporuje síťové operace, RMI
- interpretovaný (?)
- robustní
- bezpečný
- nezávislý na architektuře - překládá se pro JVM (run-time + knihovny)
- přenositelný
- výkonný
- vícevláknový
- dynamický - podporuje reflexi
Datové typy
Základní
Typ | Popis | Default | Velikost |
boolean | true nebo false | false | 1 bit |
char | UNICODE znak | \u0000 | 16 bitů |
byte | celé číslo se znaménkem | 0 | 8 bitů |
short | celé číslo se znaménkem | 0 | 16 bitů |
int | celé číslo se znaménkem | 0 | 32 bitů |
long | celé číslo se znaménkem | 0 | 64 bitů |
float | IEEE 754 floating-point | 0.0 | 32 bitů |
double | IEEE 754 floating-point | 0.0 | 64 bitů |
Odvozené
- objekty
String s = "text";
String p = new String();
- pole
byte[] a = new byte[4];
byte b[] = new byte[4];
Objekty, třídy a interfacy
- "všechno je objekt"
- objekty jsou instance tříd
Circle c = new Circle();
double a;
c.x = 0.0;
c.y = 1.0;
c.r = 2.0;
a = c.area();
- třída je soubor dat a metod pracujících s těmito daty
public class Circle {
public double x, y;
public double r;
public double circumference() { return 2 * java.lang.Math.Pi * r; }
public double area() { return r * r * java.lang.Math.Pi; }
}
public class GraphicCircle implements Drawable extends Circle {
Color outline, fill;
public void draw(DrawWindow w) { dw.drawCircle(x, y, r, outline, fill); }
}
- interface je soubor definic konstant a/nebo metod; třída může
implementovat jeden nebo více interfaců
public interface Drawable {
public void draw(DrawWindow dw);
}
- definice interface vytváří nový datový typ (abstraktní třída)
Drawable d = new GraphicCircle();
Výjimky
public void open() throws IOException {
}
try {
}
catch(ExceptionType1 e) {
}
catch(ExceptionType2 e) {
}
finally {
}
- obdoba výjimek v C++
- ohlašují chybové stavy
- synchronní - vzniklé v samotném programu (přetečení při operacích
v plovoucí čárce, index mimo meze, přístup k nepovolené metodě apod.)
- asynchronní - vzniklé mimo program (přerušení od systému)
- každá metoda musí deklarovat, jaké výjimky v ní mohou vzniknout,
nebo tyto výjimky chytit (výjimkou jsou "normální" výjimky)
- neodchycené výjimky se propagují do nadřazených bloků a metod
- výjimka je objekt třídy odvozené od Throwable
- fatální chyby jsou výjimky odvozené od Error, nefatální
výjimky jsou odvozené od Exception
Vzdálené volání metod
- synchronní volání metod objektů, které jsou v jiných JVM
- volaná metoda musí být implementací metody interfacu odvozeného
od java.rmi.Remote
- volaný objekt musí být odvozen od třídy
java.rmi.server.RemoteObject
- klientovy lokální parametry se předávají hodnotou (objekty musí
implementovat interface java.io.Serializable
- vzdálené objekty se předávají odkazem (hodnotou se předává
lokální proxy objekt)
- klient se na vzdálený objekt může odkazovat pouze přes definovaný
interface odvozený od java.rmi.Remote
Rozdíly proti jazykům C a C++
- program v Javě je jedna nebo více definic tříd, jedna z nich má
metodu main()
- každá třída je uložena ve vlastním souboru .class
- programy v Javě nemají přístup k environmentu (JVM nemá
environment)
- neexistují globální proměnné
- každá třída je uložena ve svém souboru; tyto soubory se dynamicky
vkládají
- nepoužívá preprocesor
- znaky jsou v UNICODE
- primitivní typy mají pevně danou velikost
- všechny odvozené typy jsou předávány odkazem (pole a objekty)
- neexistují ukazatele
- objekty se musí vytvářet explicitně (objektové proměnné jsou
pouze reference) - včetně přiřazování clone()
- neexistují destruktory - používá se "garbage collector"
- indexy polí se automaticky kontrolují
- výraz nemůže obsahovat znak ","
- neexistuje příkaz goto
- příkazy break a continue mohou odkazovat na
label
- pro synchronizaci vláken existuje příkaz synchronized
- jsou povolené budoucí odkazy (forward reference)
- neexistují struktury, uniony, výčtové typy, bitová pole, funkce s
proměnným počtem parametrů, typedef
- všechny metody jsou virtuální
- neexistuje vícenásobná dědičnost
- nelze přetěžovat operátory
- neexistují templaty
Výkon
- Java nebyla určena pro náročné výpočty
- výkon ovlivňuje systém výjimek, testování hodnot, referencí, úklid
- při interpretaci - řádově 20x pomalejší než C/C++
- při kompilaci - přibližně dvakrát pomalejší
- neexistují principiální omezení výkonu (proti C/C++)
import java.lang.Math;
public class DWhet {
public static double t1, t2, t3;
public static int j, k, l;
public static double e1[];
public static void main(String[] args) {
int i, isave;
int n2, n3, n4, n6, n7, n8, n9, n11;
int inner, outer, kount, npass, max_pass;
double x, y, z;
double whet_save, dif_save, kilowhet;
double begin_time, end_time, dif_time;
double error, whet_err, percent_err;
double secnds;
e1 = new double[5];
npass = 0;
max_pass = 2;
inner = 1000;
outer = 20;
while(npass < max_pass) {
System.out.print("Pass number: ");
System.out.println(npass);
kount = 0;
while(kount < outer) {
t1 = 0.499975;
t2 = 0.50025;
t3 = 2.0;
isave = inner;
n2 = 12 * inner;
n3 = 14 * inner;
n4 = 345 * inner;
n6 = 210 * inner;
n7 = 32 * inner;
n8 = 899 * inner;
n9 = 616 * inner;
n11 = 93 * inner;
e1[1] = 1.0;
e1[2] = -1.0;
e1[3] = 1.0;
e1[4] = -1.0;
// Loop 2
for(i = 1; i <= n2; i++) {
e1[1] = ( e1[1] + e1[2] + e1[3] - e1[4]) * t1;
e1[2] = ( e1[1] + e1[2] - e1[3] + e1[4]) * t1;
e1[3] = ( e1[1] - e1[2] + e1[3] + e1[4]) * t1;
e1[4] = (-e1[1] + e1[2] + e1[3] + e1[4]) * t1;
}
// Loop 3
for(i = 1; i <= n3; i++) {
sub1(e1);
}
// Loop 4
j = 1;
for (i = 1; i <= n4; i++) {
if(j - 1 != 0) {
j = 2;
} else {
j = 3;
}
if(j - 2 != 0) {
j = 1;
} else {
j = 0;
}
if(j - 1 != 0) {
j = 1;
} else {
j = 0;
}
}
// Loop 6
j = 1;
k = 2;
l = 3;
for(i = 1; i <= n6; i++) {
j = j * (k - j) * (l - k);
k = l * k - (l - j) * k;
l = (l - k) * (k + j);
e1[l - 1] = j + k + l;
e1[k - 1] = j * k * l;
}
// Loop 7
x = 0.5;
y = 0.5;
for(i = 1; i <= n7; i++) {
x = t1 * Math.atan( t3 * Math.sin( x ) * Math.cos( x ) / (Math.cos( x + y ) + Math.cos( x - y ) - 1.0) );
y = t1 * Math.atan( t3 * Math.sin( y ) * Math.cos( y ) / (Math.cos( x + y ) + Math.cos( x - y ) - 1.0) );
}
// Loop 8
x = 1.0;
y = 1.0;
z = 1.0;
for(i = 1; i <= n8; i++) {
sub2(x,y,z);
}
// Loop 9
j = 1;
k = 2;
l = 3;
e1[1] = 1.0;
e1[2] = 2.0;
e1[3] = 3.0;
for(i = 1; i <= n9; i++) {
sub3();
}
// Loop 11
x = 0.75;
for(i = 1; i <= n11; i++) {
x = Math.sqrt( Math.exp( Math.log( x ) / t2 ) );
}
inner = isave;
kount = kount + 1;
}
npass = npass + 1;
if(npass < max_pass) {
inner = inner * max_pass;
}
}
}
public static void sub1(double[] e) {
for(int i = 1; i <= 6; i++) {
e[1] = (e[1] + e[2] + e[3] - e[4]) * t1;
e[2] = (e[1] + e[2] - e[3] + e[4]) * t1;
e[3] = (e[1] - e[2] + e[3] + e[4]) * t1;
e[4] = (-e[1] + e[2] + e[3] + e[4]) / t3;
}
}
public static void sub2(double x, double y, double z) {
double x1, y1;
x1 = x;
y1 = y;
x1 = (x1 + y1) * t1;
y1 = (x1 + y1) * t1;
z = (x1 + y1) / t3;
}
public static void sub3() {
e1[j] = e1[k];
e1[k] = e1[l];
e1[l] = e1[j];
}
}
Použití v rozsáhlých výpočtech
- pro zapouzdření existujících výpočetních zdrojů - trojpilířová architektura:
- služby - databázové servery, objektové servery
- aplikační servery - poskytují aplikační funkce, vyvažování
zátěže, monitorování, integraci služeb
- klienti - uživatelská rozhraní, aplikační programy,
nástroje pro plánování a spolupráci
- služby jsou implementovány nativními metodami (databázové stroje,
programy v C/C++/Fortran)
- aplikační servery prezentují služby pomocí standardizovaných
rozhraní a protokolů CORBA, HTTP, Java RMI, ...
- přímo pro programování náročných aplikací
- výhody - široká programátorská základna, vlastnosti jazyka
(robustnost, možnost optimalizace díky nepřítomnosti ukazatelů),
nezávislost na architektuře
- nevýhody - prozatím malý výkon, nezávislost na architektuře