adding comparison between java and java-tx code and changing section about overwriting methods
This commit is contained in:
parent
44703189f2
commit
2e1ed31206
295
main.tex
295
main.tex
@ -22,7 +22,7 @@
|
|||||||
showstringspaces=false,
|
showstringspaces=false,
|
||||||
showtabs=false,
|
showtabs=false,
|
||||||
breaklines=true,
|
breaklines=true,
|
||||||
tabsize=4,
|
tabsize=4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -43,17 +43,19 @@
|
|||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item Motivation
|
\item Motivation
|
||||||
\item Aufbau der Umgebung
|
\item Aufbau der Umgebung
|
||||||
\item Probleme
|
\item Bugs/Probleme
|
||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item Überschreibung von Methoden
|
\item Überschreiben von Methoden
|
||||||
\item Lambda Ausdrücke
|
\item Kompatibilität mit funktionalen Interfaces
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
\item Bugs
|
\vspace*{-\baselineskip}
|
||||||
|
\item Fazit
|
||||||
|
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
\begin{frame}
|
\begin{frame}
|
||||||
\frametitle{Motivation}
|
\frametitle{Motivation I}
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Welche Features fehlen noch in Java-TX?
|
\item Welche Features fehlen noch in Java-TX?
|
||||||
@ -65,7 +67,7 @@
|
|||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
\begin{frame}
|
\begin{frame}
|
||||||
\frametitle{Motivation}
|
\frametitle{Motivation II}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=3]
|
\begin{tikzpicture}[scale=3]
|
||||||
\draw (1,0) -- (0,0) -- (0,1) -- (3,1) -- (3,0) -- (2,0) -- (2, -1.1) -- (1, -1.1) -- cycle;
|
\draw (1,0) -- (0,0) -- (0,1) -- (3,1) -- (3,0) -- (2,0) -- (2, -1.1) -- (1, -1.1) -- cycle;
|
||||||
@ -80,9 +82,76 @@
|
|||||||
\end{center}
|
\end{center}
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]{Vergleich Sourcecode}
|
||||||
|
\begin{columns}
|
||||||
|
\begin{onlyenv}<1->
|
||||||
|
\begin{column}{0.5\textwidth}
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
public class FunNClass extends ClassOrInterface {
|
||||||
|
private static GenericDeclarationList createGenerics(List<GenericRefType> funNParams) {
|
||||||
|
var generics = new ArrayList<GenericTypeVar>();
|
||||||
|
for (GenericRefType param : funNParams) {
|
||||||
|
generics.add(...);
|
||||||
|
}
|
||||||
|
return new GenericDeclarationList(generics, new NullToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{column}
|
||||||
|
\end{onlyenv}
|
||||||
|
\begin{onlyenv}<1>
|
||||||
|
\begin{column}{0.5\textwidth}
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
public class FunNClass extends ClassOrInterface {
|
||||||
|
private static createGenerics(funNParams) {
|
||||||
|
|
||||||
|
|
||||||
|
var generics = new ArrayList<GenericTypeVar>();
|
||||||
|
for (GenericRefType param : funNParams) {
|
||||||
|
generics.add(...);
|
||||||
|
}
|
||||||
|
return new GenericDeclarationList(generics, new NullToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{column}
|
||||||
|
|
||||||
|
\end{onlyenv}
|
||||||
|
\begin{onlyenv}<2->
|
||||||
|
\begin{column}{0.5\textwidth}
|
||||||
|
\begin{lstlisting}[language=java, escapechar=!]
|
||||||
|
public class FunNClass extends ClassOrInterface {
|
||||||
|
private static GenericDeclarationList createGenerics(Iterable<? extends GenericRefType> var0) {
|
||||||
|
List var1 = null;
|
||||||
|
var1 = (List)(new ArrayList());
|
||||||
|
Iterator var10000 = var0.iterator();
|
||||||
|
while(var10000.hasNext()) {
|
||||||
|
GenericRefType var2 = (GenericRefType)var10000.next();
|
||||||
|
var1.add(...);
|
||||||
|
}
|
||||||
|
return new GenericDeclarationList(var1, new NullToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{column}
|
||||||
|
\end{onlyenv}
|
||||||
|
\end{columns}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}{Aufbau der Umgebung I}
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Compiler soll sukzessive in Java-TX umgeschrieben werden
|
||||||
|
\item Umgebung mit .java und .jav Dateien
|
||||||
|
\item Ziel: Auf JVM ausführbare .class Dateien
|
||||||
|
\item Java-TX Compiler kann .java Dateien lesen \\
|
||||||
|
\(\rightarrow\) Abhängigkeiten zu Java Dateien möglich
|
||||||
|
\item Java-TX Compiler muss vor javac aufgerufen werden
|
||||||
|
\end{enumerate}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
\begin{frame}[fragile]
|
\begin{frame}[fragile]
|
||||||
\frametitle{Aufbau der Umgebung}
|
\frametitle{Aufbau der Umgebung II - make}
|
||||||
Erster Versuch mit make:
|
Erster Ansatz mit make:
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
# Use find to locate all .java and .jav files recursively
|
# Use find to locate all .java and .jav files recursively
|
||||||
JAVASOURCES := $(shell find $(SRCDIR) -name '*.java')
|
JAVASOURCES := $(shell find $(SRCDIR) -name '*.java')
|
||||||
@ -102,11 +171,11 @@
|
|||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
|
|
||||||
\begin{frame}[fragile]
|
\begin{frame}[fragile]{Aufbau der Umgebung III}
|
||||||
Probleme:
|
Probleme:
|
||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item javac compiliert und trackt Änderungen der Abhängigkeiten automatisch
|
\item javac compiliert und trackt Änderungen der Abhängigkeiten automatisch
|
||||||
\item javac ist sehr langsam wenn für jede Datei einzeln aufgerufen
|
\item javac ist sehr langsam wenn für jede Datei einzeln aufgerufen (viele mehrfache Compilierungen)
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
\begin{columns}
|
\begin{columns}
|
||||||
\begin{column}{0.5\textwidth}
|
\begin{column}{0.5\textwidth}
|
||||||
@ -116,18 +185,18 @@ javac src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java
|
|||||||
...
|
...
|
||||||
javac src/main/java/Main.java
|
javac src/main/java/Main.java
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
\sim{}5min
|
$\sim{}$5min Compilerzeit
|
||||||
\end{column}
|
\end{column}
|
||||||
\begin{column}{0.5\textwidth}
|
\begin{column}{0.5\textwidth}
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
javac src/main/java/de/dhbwstuttgart/typedeployment/TypeInsert.java src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java ... src/main/java/Main.java
|
javac src/main/java/de/dhbwstuttgart/typedeployment/TypeInsert.java src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java ... src/main/java/Main.java
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
\sim{}2sec
|
$\sim{}$2sec Compilerzeit
|
||||||
\end{column}
|
\end{column}
|
||||||
\end{columns}
|
\end{columns}
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
\begin{frame}[fragile]{Bash Script}
|
\begin{frame}[fragile]{Aufbau der Umgebung IV - compile script}
|
||||||
Gegeben: Quellverzeichnis, Zielverzeichnis
|
Gegeben: Quellverzeichnis, Zielverzeichnis
|
||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item Suche rekursiv alle .java und .jav Dateien im Quellverzeichnis und speichere sie jeweils in einer Liste
|
\item Suche rekursiv alle .java und .jav Dateien im Quellverzeichnis und speichere sie jeweils in einer Liste
|
||||||
@ -136,6 +205,7 @@ javac src/main/java/de/dhbwstuttgart/typedeployment/TypeInsert.java src/main/jav
|
|||||||
\item Wenn ja, gehe weiter zur nächsten Datei
|
\item Wenn ja, gehe weiter zur nächsten Datei
|
||||||
\item Wenn nein, füge die Quelldatei zur Liste der zu kompilierenden Dateien hinzu
|
\item Wenn nein, füge die Quelldatei zur Liste der zu kompilierenden Dateien hinzu
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
\vspace*{-\baselineskip}
|
||||||
\item Rufe den Java-TX Compiler mit allen Dateien in der jav-Liste als Argumente auf
|
\item Rufe den Java-TX Compiler mit allen Dateien in der jav-Liste als Argumente auf
|
||||||
\lstinline{java -jar $JAVATX_COMPILER_PATH -d $DESTDIR -cp "$SRCDIR:$DESTDIR:target/dependencies/" "${JAV_CHANGED[@]}"}
|
\lstinline{java -jar $JAVATX_COMPILER_PATH -d $DESTDIR -cp "$SRCDIR:$DESTDIR:target/dependencies/" "${JAV_CHANGED[@]}"}
|
||||||
\item Rufe den javac Compiler mit allen Dateien in der java-Liste als Argumente auf
|
\item Rufe den javac Compiler mit allen Dateien in der java-Liste als Argumente auf
|
||||||
@ -144,7 +214,7 @@ javac src/main/java/de/dhbwstuttgart/typedeployment/TypeInsert.java src/main/jav
|
|||||||
|
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
\begin{frame}[fragile]{Bugs}
|
\begin{frame}[fragile]{Bugübersicht}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture} \begin{axis}[ ybar, enlargelimits=0.15, legend style={at={(0.
|
\begin{tikzpicture} \begin{axis}[ ybar, enlargelimits=0.15, legend style={at={(0.
|
||||||
5,-0.3)}, anchor=north,legend columns=-1}, ylabel={amount}, symbolic x
|
5,-0.3)}, anchor=north,legend columns=-1}, ylabel={amount}, symbolic x
|
||||||
@ -158,4 +228,199 @@ javac src/main/java/de/dhbwstuttgart/typedeployment/TypeInsert.java src/main/jav
|
|||||||
\end{center}
|
\end{center}
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]{Primitive Typen in Java-TX}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Java erlaubt neben Referenztypen auch primitive Datentypen (int, boolean, ...)
|
||||||
|
\item Java-TX erlaubt primitive Datentypen zwar im Quellcode, wandelt diese aber in die korrespondierende Wrapperklasse um (Integer, Boolean, ...)
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\begin{columns}
|
||||||
|
\begin{column}{0.5\textwidth}
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
int a = 10;
|
||||||
|
boolean b = true;
|
||||||
|
float c = 10.0f;
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{column}
|
||||||
|
\begin{column}{0.5\textwidth}
|
||||||
|
\begin{lstlisting}
|
||||||
|
Integer var1 = null;
|
||||||
|
var1 = 10;
|
||||||
|
Boolean var2 = null;
|
||||||
|
var2 = true;
|
||||||
|
Float var3 = null;
|
||||||
|
var3 = 10.0F;
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{column}
|
||||||
|
\end{columns}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\begin{itemize}
|
||||||
|
\item Generell in Java: Methoden nicht anhand von Rückgabewert überschreibbar
|
||||||
|
\end{itemsize}
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
public class Bar {
|
||||||
|
int foo(Object obj){return 0;}
|
||||||
|
boolean foo(Object obj){return false;}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\begin{lstlisting}
|
||||||
|
Bar.java:3: Fehler: Methode foo(Object) ist bereits in Klasse Bar definiert
|
||||||
|
boolean foo(Object obj){return false;}
|
||||||
|
^
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item Aber: Generell auf JVM lauffähig
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]{Überschreiben von Methoden II}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Überschreiben von Java Methoden mit primitiven Datentypen als Parameter funktionierte nicht
|
||||||
|
\end{itemize}
|
||||||
|
\vspace*{-\baselineskip}
|
||||||
|
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
public boolean equals(Object obj);
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
//Java-TX Code
|
||||||
|
import java.lang.Object;
|
||||||
|
import java.lang.Boolean;
|
||||||
|
public class Foo {
|
||||||
|
equals(Object o){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
//Inferierte Typen
|
||||||
|
public class Foo {
|
||||||
|
public Foo() {}
|
||||||
|
Boolean equals(Object var1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]{Überschreiben von Methoden III}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Lösung: Wenn Methodensignatur eines Supertyps sich nur in primitiven-/Wrapper-Datentypen unterscheidet, werden Typen vom Supertyp in Subtyp substituiert
|
||||||
|
\end{itemize}
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
import java.lang.Object;
|
||||||
|
import java.lang.Boolean;
|
||||||
|
|
||||||
|
public class Foo {
|
||||||
|
equals(Object o){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
public class Foo {
|
||||||
|
public Foo() {}
|
||||||
|
boolean equals(Object var1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
|
||||||
|
\begin{frame}[fragile]{Kompatibilität mit funktionalen Interfaces I}
|
||||||
|
\begin{itemize}
|
||||||
|
\item In Java haben Lambda Ausdrücke als Target Type ein funktionales Interface z.B. java.util.function.Function
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
Function<Integer, Integer> func = x -> x*2;
|
||||||
|
\end{lstlisting}
|
||||||
|
\item Java-TX unterstützt echte Funktionstypen
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
var func = x -> x*2;
|
||||||
|
func: Fun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$
|
||||||
|
\end{lstlisting}
|
||||||
|
\item Für Kompatibilität müssen Funktionstypen mit Target Typen integriert werden
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]{Kompatibilität mit funktionalen Interfaces II}
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item Problem: Lambda Ausdrücke haben in Java-TX einen FunN\$\$ Typ (für N = \#Parameter)
|
||||||
|
\item Aber: Java Bibliotheken wie Stream erwarten verschiedene funktionale Interfaces
|
||||||
|
\item Lösung: Lambda Ausdrücke müssen je nach Kontext erwartetes funktionales Interface als Target Typ haben
|
||||||
|
\end{itemize}
|
||||||
|
Beispiel:
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Steam;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
main() {
|
||||||
|
List<Integer> list = new ArrayList<>(List.of(1,2,3,4,5));
|
||||||
|
return list.stream().map(x -> x*2).toList();
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]{Kompatibilität mit funktionalen Interfaces III}
|
||||||
|
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
<R> Stream<R> map(Function<? super T, ? extends R> var1);
|
||||||
|
\end{lstlisting}
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
public interface Function<T, R> {
|
||||||
|
R apply(T var1);
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\vspace*{\baselineskip}
|
||||||
|
\begin{itemize}
|
||||||
|
\item Eigentlich würde Java-TX Fun1\$\$\ $\langle{}Integer, Integer\rangle{}$ inferieren
|
||||||
|
\item Aber: Stream.map erwartet $Function\langle{}? super T, ? extends R\rangle{}$
|
||||||
|
\end{itemize}
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
...
|
||||||
|
3: invokedynamic #41, 0 // InvokeDynamic #0:apply:(LFoo;)LFun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$;
|
||||||
|
//Invalid Bytecode
|
||||||
|
5: invokeinterface #45, 2 // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
|
||||||
|
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]{Kompatibilität mit funktionalen Interfaces IV}
|
||||||
|
\begin{lstlisting}[language=java]
|
||||||
|
...
|
||||||
|
50: invokedynamic #60, 0 // InvokeDynamic #0:apply:(LFoo;)Ljava/util/function/Function;
|
||||||
|
55: invokeinterface #66, 2 // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
|
||||||
|
...
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
|
||||||
|
\begin{frame}{Fazit}
|
||||||
|
Vorteile:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Programmierer muss weniger Typen explizit angeben
|
||||||
|
\item Funktionstypen erlauben übersichtlichere Subtypisierung von anonymen Funktionen als Java
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Nachteile:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Alle verwendeten/berückstichtigten Typen müssen manuell importiert werden \\
|
||||||
|
\(\rightarrow\) Der Programmierer muss schon wissen, welche Typen in Frage kommen
|
||||||
|
\item Es ist möglich, dass ein ungeschünschter Typ inferiert wird
|
||||||
|
\item Aktuell begrenzte Sprachfeatures \& vermutlich einige Bugs
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\end{frame}
|
||||||
\end{document}
|
\end{document}
|
Loading…
Reference in New Issue
Block a user