Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Der Java-Experten-Kurs Constants, Inlining, Classloaders Karl Pauls Final is not Final anymore private 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 anymore public 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 anymore public 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.5 Book title: Beginning C++ Author: Michael Dawson Year: 2005 Publisher: Prentice Hall Number of pages: 500 Constants public 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 Constants public 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 Constants public 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); } } Literal LiteralPlus LiteralNew LiteralConcat Constants 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 nicht StaticFinalTestClient neu übersetzt? Constants Literal LiteralPlus LiteralNewXXX LiteralConcatXXX 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 ! Constants 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; } public class Main implements InterfaceA, InterfaceB, InterfaceC { public static void main (String [] args){ System.out.println (A + B + C); 7 } } Constants 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; } public class Main implements InterfaceA, InterfaceB, InterfaceC{ public static void main (String [] args) { System.out.println (C + B + A); 6 } } Namen von Klassen //: a1/A.java public class A { public String toString() { return "This is the first class"; } } //: a2/A.java public 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 NormalTest This is the first class > java -classpath .;a2 NormalTest This is the second class Kann man auch beides haben? Classloader ClassLoader 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 } } Classloaders import 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 A c2.toString(): class A c1.equals(c2): false c1.newInstance(): This is the first class c2.newInstance(): This is the second class Parent Classloader public class Parent { public String toString() { return "Thanks for caring... but what do you want??? "; }} //: a1/A.java public class A extends Parent { public String toString() { return super.toString() + "This is the first class"; }} //: a2/A.java public 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 class Thanks for caring... but what do you want??? This is the second class True False java.lang.ClassCastException: A at Loader.main(Loader.java:18) We expected to get ClassCastException Parent 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/")}, 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 class Thanks for caring... but what do you want??? This is the second class true true We 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