Why is my reflection loading weird classes?

I'm trying to play with thought to see if I can get to the point where I can enter the class name, and my application will load this class and instantiate it. After several attempts that I discovered, I could not just insert the class name in Class.forName() without its package name, so I got an attempt to get a list of all available packages that were loaded, and trying to load the type I type in with each name pack until he gets hit.

This is what I have so far:

 BufferedReader console = new BufferedReader(new InputStreamReader(System.in)); String s = ""; do { ClassLoader clsldr = ClassLoader.getSystemClassLoader(); Package[] pkgs = Package.getPackages(); s = console.readLine(); if(s.equals(":exit")) { System.exit(0); } boolean classFound = false; Object loadedClass = null; String classname = ""; for (int i = 0; i < pkgs.length; i++) { Package package1 = pkgs[i]; try { classname = package1.getName().replace('/', '.') + "." + s; clsldr.loadClass(classname); loadedClass = Class.forName(classname); classFound = true; } catch(Exception e) { } } System.out.println("LOADED A CLASS!!!!"); System.out.println(classname); System.out.println(loadedClass); } while(s.length() == 0); 

This floor works very weird. For example, when I enter “Object” at the prompt, it somehow manages to load sun.net.util.Object , but when I print the actual object, it prints class java.lang.Object . I get the same with String , as well as several other things that I typed. One interesting thing I tried was int - it loaded sun.net.util.int , and when I printed the object, it just returned null. Another thing happened when I tried Java :

 Java LOADED A CLASS!!!! sun.net.util.Java null 

Does anyone know what is going on here? Is there something special in the sun.net.util package that causes this? I don’t care that my code doesn’t work exactly the way I want, I just wanted to know what causes this strange behavior.

Java version:

 java version "1.7.0_25" Java(TM) SE Runtime Environment (build 1.7.0_25-b17) Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode) 

I am using the 64-bit version of Windows 8, if that matters.

+6
source share
3 answers

I just thought about something: I never get out of my loop when I'm in class. Thus, it is probably actually possible to get to java.lang.Object , which sets the class loaded to true, but it continues in a loop that overwrites the loaded class, and sun.net.util , probably the last package loaded in my system. All I need is a break statement, and it must stop this behavior.

0
source

Your code returns “weird” classes, because what it does is conceptually broken. There is nothing in any specification that indicates the physical order of the entries in the rt.jar file. They just end up in the order, which leads to the fact that you discover the “weird” way you do iteration. In another release of Java, your code may give you a "non-strange" Object class. In any case, the assumption that you get the “correct” class this way is ... erroneous.


You say you are doing this because:

"I wanted to take a hit on creating a Java interpreter"

Well, if you're going to implement an interpreter, you need to understand the Java language. And one of the things you need to understand is that in Java there can be many classes with the same simple name. This means that your idea of ​​scanning a classpath for any class with a given simple name is simply impractical. You will find that there are too many “collisions” (for example, classes with the same simple name) for commonly used classes.

In normal Java, this collision problem is addressed either by accessing classes by their fully qualified names, or by importing them. For your interpreter to be useful, you need to implement an import scheme that reflects the usual Java import mechanism.

In short, flip the code above and start again.

+3
source

Classes starting with sun and com.sun are internal and mostly undocumented "housekeeping" classes that are used by the internal components of the JVM. They are not part of the Java API, but different JVMs will have different ones. The fact that you see all of these different internal components is the reason that you must provide the fully qualified name for the Reflection API .; -)

0
source

Source: https://habr.com/ru/post/951355/


All Articles