So let’s have a look at a very interesting way of loading a class.
UnIntrestingClass.java
We have a very simple class. There is nothing special about it. It just prints text in constructor.
package com.programtalk.learn.java.beginner; public class UnIntrestingClass { public UnIntrestingClass() { System.out.println("So Where did i come from!"); } }
ByteCodeGenerator.java
This class prints the bytecode of the UnIntrestingClass. This class just shows how to print the bytecode.
package com.programtalk.learn.java.beginner; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; public class ByteCodeGenerator { public static void main(String[] args) throws IOException, URISyntaxException { URL urlClass = UnIntrestingClass.class.getResource("UnIntrestingClass.class"); byte array[] = Files.readAllBytes(Paths.get(urlClass.toURI())); String UnIntrestingClassBytecode = Base64.getEncoder().encodeToString(array); System.out.println(UnIntrestingClassBytecode ); } }
It prints
yv66vgAAADQAHgcAAgEANWNvbS9wcm9ncmFtdGFsay9sZWFybi9qYXZhL2JlZ2lubmVyL1VuSW50cmVzdGluZ0NsYXNzBwAEAQAQamF2YS9sYW5nL09iamVjdAEABjxpbml0PgEAAygpVgEABENvZGUKAAMACQwABQAGCQALAA0HAAwBABBqYXZhL2xhbmcvU3lzdGVtDAAOAA8BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsIABEBABlTbyBXaGVyZSBkaWQgaSBjb21lIGZyb20hCgATABUHABQBABNqYXZhL2lvL1ByaW50U3RyZWFtDAAWABcBAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAN0xjb20vcHJvZ3JhbXRhbGsvbGVhcm4vamF2YS9iZWdpbm5lci9VbkludHJlc3RpbmdDbGFzczsBAApTb3VyY2VGaWxlAQAWVW5JbnRyZXN0aW5nQ2xhc3MuamF2YQAhAAEAAwAAAAAAAQABAAUABgABAAcAAAA/AAIAAQAAAA0qtwAIsgAKEhC2ABKxAAAAAgAYAAAADgADAAAAAwAEAAQADAAFABkAAAAMAAEAAAANABoAGwAAAAEAHAAAAAIAHQ==
InterestingLoadClass.java
Let us assume this is a class in which we want to use UnIntrestingClass, without importing the class or having the class in the classpath. So we can do that by using the bytecode of the class.
package com.programtalk.learn.java.beginner; public class InterestingLoadClass { public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException { new ClassLoader() { public Class<?> findClass(String c) { byte[] bytecode = java.util.Base64.getDecoder() .decode("yv66vgAAADQAHgcAAgEANWNvbS9wcm9ncmFtdGFsay9sZWFybi9qYXZhL2JlZ2lubmVyL1VuSW50cm" + "VzdGluZ0NsYXNzBwAEAQAQamF2YS9sYW5nL09iamVjdAEABjxpbml0PgEAAygpVgEABENvZGUKAAMACQwAB" + "QAGCQALAA0HAAwBABBqYXZhL2xhbmcvU3lzdGVtDAAOAA8BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsI" + "ABEBABlTbyBXaGVyZSBkaWQgaSBjb21lIGZyb20hCgATABUHABQBABNqYXZhL2lvL1ByaW50U3RyZWFtDAAWABcBA" + "AdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxl" + "AQAEdGhpcwEAN0xjb20vcHJvZ3JhbXRhbGsvbGVhcm4vamF2YS9iZWdpbm5lci9VbkludHJlc3RpbmdDbGFzczsBAApTb3VyY2VGa" + "WxlAQAWVW5JbnRyZXN0aW5nQ2xhc3MuamF2YQAhAAEAAwAAAAAAAQABAAUABgABAAcAAAA/AAIAAQAAAA0qtwAIsgAKEhC2ABKxAAAAAg" + "AYAAAADgADAAAAAwAEAAQADAAFABkAAAAMAAEAAAANABoAGwAAAAEAHAAAAAIAHQ=="); return defineClass("test.UnIntrestingClass", bytecode, 0, bytecode.length); } }.loadClass("com.programtalk.learn.java.beginner.UnIntrestingClass").newInstance(); } }
And it prints
So Where did i come from!
Summary
I recenty saw this in one of the articles and found it quite interesting. As you can see I am using the class UnIntrestingClass
in InterestingLoadClass
without needing to import this class or have that class in my classpath.