Der Java-Experten-KursFinal is not Final anymore private static void change(Book p, String name,...

Post on 04-Jun-2020

3 views 0 download

Transcript of Der Java-Experten-KursFinal is not Final anymore private static void change(Book p, String name,...

Der Java-Experten-Kurs

Karl Pauls

Constants, Inlining, Classloaders

Final is not Final anymoreprivate static void change(Book p, String name, Object value)

throws NoSuchFieldException, IllegalAccessException {

Field field = Book.class.getDeclaredField(name); field.setAccessible(true); field.set(p, value);

} public class Book {

private final String title; private final String author; private final int year; private final int numberOfPages = 500; private final Object publisher = "Addison Wesley";

Final is not Final anymorepublic static void main(String[] args) { Book book = new Book("Core Java(TM) 2",

”Gary Cornell", 2000); change(book, "title", "Beginning C++"); change(book, "author", "Michael Dawson"); change(book, "year", new Integer(2005)); change(book, "publisher", "Prentice Hall"); change(book, "numberOfPages", new Integer(1000)); System.out.println(book);

java.lang.IllegalAccessException: Field is final Book title: Core Java(TM) 2 Author: Gary Cornell Year: 2000 Publisher: Addison We Number of pages: 500

Final is not Final anymorepublic static void main(String[] args) { Book book = new Book("Core Java(TM) 2",

”Gary Cornell", 2000); change(book, "title", "Beginning C++"); change(book, "author", "Michael Dawson"); change(book, "year", new Integer(2005)); change(book, "publisher", "Prentice Hall"); change(book, "numberOfPages", new Integer(1000)); System.out.println(book);

Jdk 1.5Book title: Beginning C++ Author: Michael Dawson Year: 2005 Publisher: Prentice Hall Number of pages: 500

Constantspublic class Main implements InterfaceA {   public static void main (String [] args)   {       System.out.println (A);   } }public interface InterfaceA{ public static final int A = 1;}

Method void main(java.lang.String[])  0 getstatic #23 <Field java.io.PrintStream out>  3 iconst_1_  4 invokevirtual #29 <Method void println(int)>  7 return

Constantspublic interface InterfaceA{   public static final int A =

new java.util.Random ().nextInt ();}

Method void main(java.lang.String[]) 0 getstatic #27 <Field java.io.PrintStream out> 3 getstatic #31 <Field int A> 6 invokevirtual #37 <Method void println(int)> 9 return

Inlined

Constantspublic interface StaticFinalTest {

String LITERAL = "Literal"; String LITERAL_PLUS = "Literal" + "Plus"; String LITERAL_NEW = new String("LiteralNew"); String LITERAL_CONCAT = "LiteralConcat".concat("");

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

System.out.println(StaticFinalTest.LITERAL); System.out.println(StaticFinalTest.LITERAL_PLUS); System.out.println(StaticFinalTest.LITERAL_NEW); System.out.println(StaticFinalTest.LITERAL_CONCAT);

}}

ConstantsLiteralLiteralPlusLiteralNewLiteralConcat

public interface StaticFinalTest { String LITERAL = "LiteralXXX"; String LITERAL_PLUS = "Literal" + "PlusXXX"; String LITERAL_NEW = new String("LiteralNewXXX"); String LITERAL_CONCAT = "LiteralConcat".concat("XXX");}

Was passiert wenn man nur StaticFinalTest aber nichtStaticFinalTestClient neu übersetzt?

ConstantsLiteralLiteralPlusLiteralNewXXXLiteralConcatXXX

public interface StaticFinalTest { String LITERAL = "LiteralXXX"; String LITERAL_PLUS = "Literal" + "PlusXXX"; String LITERAL_NEW = new String("LiteralNewXXX"); String LITERAL_CONCAT = "LiteralConcat".concat("XXX");}

-> Immer alles !

Constantspublic interface InterfaceA{  public static final int A = 2 * InterfaceB.B;}public interface InterfaceB{  public static final int B = InterfaceC.C + 1;}public interface InterfaceC extends InterfaceA{ public static final int C = A + 1;}public class Main implements InterfaceA,

InterfaceB, InterfaceC { public static void main (String [] args){     System.out.println (A + B + C); }}

7

Constants

public class Main implements InterfaceA, InterfaceB, InterfaceC{

public static void main (String [] args)  {

System.out.println (C + B + A); }}

public interface InterfaceA{  public static final int A = 2 * InterfaceB.B;}public interface InterfaceB{  public static final int B = InterfaceC.C + 1;}public interface InterfaceC extends InterfaceA{ public static final int C = A + 1;}

6

Namen von Klassen//: a1/A.javapublic class A {

public String toString() { return "This is the first class";

}}//: a2/A.javapublic class A {

public String toString() { return "This is the second class";

}}public class NormalTest {

public static void main(String[] args) { System.out.println(new A());

}}

Classpath> javac -classpath .;a1 NormalTest.java> java -classpath .;a1 NormalTestThis is the first class

> java -classpath .;a2 NormalTestThis is the second class

Kann man auch beides haben?

ClassloaderClassLoader loader = new NetworkClassLoader( host, port); Object main = loader.loadClass("Main", true).newInstance();

class NetworkClassLoader extends ClassLoader { String host; int port; public Class findClass(String name) { byte[] b = loadClassData(name); return defineClass(name, b, 0, b.length); } private byte[] loadClassData(String name) { // load the class data from the connection }}

Classloadersimport java.net.*;public class Loader { public static void main(String[] args) throws Exception { ClassLoader a1 = new URLClassLoader(new URL[] { new URL("file:a1/")}, null); ClassLoader a2 = new URLClassLoader(new URL[] { new URL("file:a2/")}, null); Class c1 = a1.loadClass("A"); Class c2 = a2.loadClass("A"); System.out.println("c1.toString(): " + c1); System.out.println("c2.toString(): " + c2); System.out.println("c1.equals(c2): " + c1.equals(c2)); System.out.println("c1.newInstance(): " + c1.newInstance()); System.out.println("c2.newInstance(): " + c2.newInstance()); }}

Classloaders cont.

c1.toString(): class Ac2.toString(): class Ac1.equals(c2): falsec1.newInstance(): This is the first classc2.newInstance(): This is the second class

Parent Classloaderpublic class Parent { public String toString() { return "Thanks for caring... but what do you want??? "; }}

//: a1/A.javapublic class A extends Parent { public String toString() { return super.toString() + "This is the first class"; }}//: a2/A.javapublic class A extends Parent { public String toString() { return super.toString() + "This is the second class"; }}

Parent Classloader cont.import java.net.*;public class Loader { public static void main(String[] args) throws Exception { ClassLoader parent = new URLClassLoader(new URL[] { new URL("file:./")}, null); ClassLoader a1 = new URLClassLoader(new URL[] { new URL("file:a1/")}, parent); ClassLoader a2 = new URLClassLoader(new URL[] { new URL("file:a2/")}, parent); Class c1 = a1.loadClass("A"); Class c2 = a2.loadClass("A"); System.out.println(c1.newInstance()); System.out.println(c2.newInstance()); System.out.println(c1.getSuperclass().equals(c2.getSuperclass())); System.out.println(Class.forName("Parent").equals(c1.getSuperclass())); try { Parent p = (Parent)c1.newInstance(); } catch(ClassCastException ex) { ex.printStackTrace(); } System.out.println("We expected to get ClassCastException"); }}

Parent Classloader cont.

Thanks for caring... but what do you want??? This is the first classThanks for caring... but what do you want??? This is the second classTrueFalsejava.lang.ClassCastException: A at Loader.main(Loader.java:18)We expected to get ClassCastException

Parentimport java.net.*;public class Loader { public static void main(String[] args) throws Exception { // ClassLoader parent = new URLClassLoader(new URL[] { // new URL("file:./")}, null); ClassLoader a1 = new URLClassLoader(new URL[] { new URL("file:a1/")}, Loader.class.getClassLoader());// parent); ClassLoader a2 = new URLClassLoader(new URL[] { new URL("file:a2/")}, Loader.class.getClassLoader()); //parent); Class c1 = a1.loadClass("A"); Class c2 = a2.loadClass("A"); System.out.println(c1.newInstance()); System.out.println(c2.newInstance()); System.out.println(c1.getSuperclass().equals(c2.getSuperclass())); System.out.println(Class.forName("Parent").equals(c1.getSuperclass())); try { Parent p = (Parent)c1.newInstance(); } catch(ClassCastException ex) { ex.printStackTrace(); } System.out.println("We did not expected to get ClassCastException"); }}

Parent

Thanks for caring... but what do you want??? This is the first classThanks for caring... but what do you want??? This is the second classtruetrueWe did not expected to get ClassCastException

Nailgun

Mehr als nur ein Programm pro JVM:

Mögliche Aufgaben

• Nailgun verbessern– Beliebige Programme

• Mit beliebigen Parametern– Undeploy– Stop– Usw...

• OSGi / Oscar ansehen:– http://oscar.objectweb.org– http://oscar-osgi.sf.net