Every other class in Java inherits from the Object class.
Is it possible to add a second, completely separate, class hierarchy in Java based around my own FastObject class?
My original goal in doing so was to create smaller, faster objects with less functionality specifically designed for certain algorithms. But let me be clear, I am not interested in whether or not this is a "good idea". I just want to know if it is possible; I have not been able to find a way to do so. Would it require a change to the JVM? New boot classpath functionality? Is the real solution to ignore Object and look at replacing java.lang.Class? Would using a direct Java compiler instead of a VM make my job any easier?
To be clear, I don't just want to edit the root Object class. That would require potentially re-writing the entire Java library. I don't want to replace the current hierarchy, I just want to create a separate one I can use in the same code.
No, this is not possible.
All created classes extend another class, either explicitly or implicitly. If you create a class and explicitly define which class it extends, then it extends that class. If not, then it implicitly extends Object. There is no way around this, just as there is no way to overload operators or anything of that sort. It is a fundamental design decision of the Java programming language.
All classes extend Object. The only things that don't are primitive types. The exception to this is Object itself, of course, which does not extend itself.
It may be possible for you to inject your own Object implementation by mucking with the boot classpath. However, I don't think there is any way to use a base object other than Object. You could try some byte code manipulation, but it is entirely possible that your modified class will be rejected by the class loader.
Related
I have been given an java assignment in school that requires me to create a StockQuote class. This would normally be easy, however the teacher has referred to it as a simple container class. I'm confused because everything that I read says container classes are things like java.util.Vector, java.util.Hashtable, and java.util.HashSet. I get the feeling he is using this term to mean something else, perhaps even just to mean a strightforward StockQuote class. I tried emailing him but he hasn't responded and I'd like to get a jump on the assignment. Here is the description from the assignment:
"A StockQuote class or interface. This a simple container class. Typically you would not use an interface for container classes, but you could. One rule for when to use an interface or not is to decided if there ever possibly could be more than one implementation of the class. If more than one implementation is possible, then using an interface definitely makes sense. In the case of simple container classes like this one, there probably will only be one implementation"
Any help or nudge in the right direction would be great. Thanks
In your case This a simple container class. == This a simple class..
In general your class may have some fields of other types, like String, Collections, etc. If so, you would say I have a container class because it contains/stores some data.
Interfaces don't have fields, so they are not containers.
I am wondering about replacing Java's 'extends' keyword somehow for dynamically extending a class based on a parameter(file, environment variable, db...basically anything). Is this even possible because playing with class loaders or calling constructors does not achieve this. I am not asking "should I use interface or superclass hierarchy" rather what is extending really mean under the hood in JAVA because there aren't any good description about it just the good old inheritance jargon:
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
The only way to "replace the extends keyword" is to dynamically create classes at runtime, which is entirely possible but non-trivial. Vert.x is a good example of a project that makes extensive use of dynamically-generated classes.
Java wasn't designed as a dynamic language in that sense. There are several dynamic languages out there (some of which can run on the JVM), such as JavaScript.
rather what is extending really mean under the hood...
Without getting into a long treatise on OOP, when you say Derived extends Base, it means that Derived inherits both the public and protected API of Base (which it can then add to) and also the implementation of that API. It means that code expecting to see a Base instance can accept a Derived instance, because Derived "is a" Base. This link is created a compile-time. At runtime, instantiating an instance of Derived involves all of the plumbing that instantiating a Base instance involves, plus then the added plumbing for Derived.
To achieve this you need to maintain various versions of a class based on the condition and you have to customise class loader as well because at a point when you find that you have to load a particular instance, you need to load that class which is not loaded by default class loader on JVM startup.
Its better to maintain multiple versions of the class and let JVM do its job which it does perfectly.
You can't do that with a language like Java. The information about "inheritance" is not only used by the compiler, it is also "hard-baked" into the compiled byte code.
If you really want to such kind of "dynamic" meta programming; you are better of using languages that allow you to do so; instead of "violating" a language that was never intended for such kind of usage.
To use some stupid comparison: just because you happen to know "screws" and "hammer" ... you wouldn't start to use a hammer to get those screws into the wall, would you? Instead, you would be looking for a tool that works better with "screws" than a hammer.
If you still want your code to run within a JVM; you might consider languages like jython or jruby.
While declaring a class as final , we cannot Inheritance this class , my question is why ? - from the java internals perspective.
I assume that the same principle apply to methods and instance as well.
is it somehow related to the class loader as well ? who is actually stopping me from override it?
There's nothing related to the JVM or internals (not really sure what exaclty you mean by that), it's a compile issue simply because you're breaking the rules.
If I think myself as a Java compiler, after parsing the tokens in your code I'm just going to look around for logical errors (semantic analysis) e.g. a circular inheritance scheme. The moment I see someone's attempt at extending a final class, I'm gonna go bazooka. That's it. No need to wake up the big bosses, the JVM or any other internals because the program cannot be correctly compiled in the first place.
If you want to know how the compiler works the way it does internally, think that while the compiler parses your code, it creates and fills some structures internal to itself for the purpose of error-checking and bytecode-translation. Also imagine in a simplified scenario that the final keyword attached to a class just sets a field in one of these structures attached to your class. After syntactic analysis, the compiler goes on with "logical" (semantic) analysis and checks (among other things) if some lunatic tries extending a final class. Even a brute search in an inheritance graph can pull that off. If a class is final and still has children, halt and notify the lunatic. The issue won't get more internal than the compiler.
It is nothing to do with Java internals.
The purpose of declaring a class to be final it to prevent it from being subclassed.
My question was what happening "underground" while declaring final ...
Well ... when a class is declared as final a flag is set in the class file to say this. If you then attempt to load a class that purports to be a subclass of a final class, the classloader will throw a VerifyError exception. The checks are done in the ClassLoader.defineClass(...) methods ... which are also final, so that normal programs can't interfere with them.
This aspect of classfile verification needs to be watertight for Java security reasons. If it wasn't then you could probably cause mayhem in a Java security sandbox by tricking trusted code into using (say) a mutable subtype of String.
The Java compiler also checks that you don't extend a final class, but you could subvert that by (for example) creating ".class" files by hand. Hence the need for load-time checks ...
Who is actually stopping me from override it?
Actually, it is the classloader. See above.
Let's look at it elementally, When you declare a variable as final, you did that because you don't want the value of that variable be changed for any reason afterwards, Right?.
Okay, under the assumption that you agree to that. The same principle is also applicable to classes.
Let's look at it this way: Why will you ever want to inherit a class? Probably because you want get access to the properties of the class and her behaviors (methods), Right? Once you have inherited these properties and behaviors you have the right the modify the accessible behavior to suite your precise need without having to re-implement all other behaviors. This is the value and power of in inheritance.
Hence, declaring a class as final implies that you don't want anyone to modify any behavior of the class. You tries to state that who so ever that will want use your class should use it as IS.
Therefore, any attempt to modify a final class is illogical and should be considered as error.
Eg.
Imaging if someone should be able to inherit your final Authentication class and modifying the actual authentication behavior (method). This should be a security bridge as it might compromise your reasons for setting the class as final.
Hence, it is a design practice.
I hope that make some sense?
I have two classes, one which is hardware-dependent and one which is not (let's call them HardwareDependent and HardwareIndependent respectively). The Hardware dependent class extends the hardware independent class. Now I have another class which at least must be an extension of the HardwareIndependent, but I would prefer it to be an extension of HardwareDependent when possible so it may leverage the additional functionality. Is there a possibility of using reflection or something else to accomplish this? Or is this a total technical impossibility? I suppose if all else fails, I could write the class twice, but it seems to me that is an ineffective approach. Thanks for any help in advance.
Inheritance is fixed at compile time.
It sounds like you don't want your new class to extend HardwareIndependent or HardwareDependent; you want it to use an object which could be either. You want composition and not inheritance. You're third class (we'll call it HardwareComposite) has a reference to a HardwareIndependent. Then, you can check if it is HardwareDependent at runtime with the instanceof operator, and if so cast it to HardwareDependent and use the additional facilities that provides.
If your design is forcing you to mix concepts of inheritance and composition, you might look into the Facade and Factory patterns.
Is there a way to create Java classes # at runtime
(classes methods n variables), with using Java reflection API
You can't do that using reflection. You need a bytecode manipulation library, like Jakarta BCEL.
The standard Java API provides a set of static methods, that allows you to dynamically create a class that implements one (or many) interfaces.
Those methods are part of the class java.lang.reflect.Proxy.
What do you require this for?
Interpreting the question in a very loose manor I can think of four likely options.
If you have a class that you add something too you might find that Aspect-oriented programming is what you are really after.
If you have an interface that you want to dynamically implement (as posted by barjak) what you want is java.lang.reflect.Proxy. This does not let create "code" at runtime but rather allows you link existing code to to a interface.
Finally (at three I know) you have actually building random classes at runtime. This you will need something like cglib or BCEL. While there are cases when this is required it is IMO rare.
One other option is that you don't really need runtime but rather build time. In this case you might be able to use annotations and apt (Java 5) / Processor (Java 6).
Sure there is. You need a java.lang.Class instance initially, for the target class you wish to create. Depending on your structure, this might either be passed in by a caller (if they're supplying the concrete class they want created), or you can statically access the class variable (e.g. MyFooImpl.class).
The simplest way is to call Class.newInstance(). This invokes the default, no-arg constructor (assuming there is one for the class; if not it throws an exception).
If you need to invoke a particular constructor with some argument, you need to call Class.getConstructor() to get a Constructor instance, which you can then call newInstance on.
In all cases you'll need to deal with reflection exceptions that you wouldn't get if invoking the constructor directly.
Big edit: I assume your question was about creating instances of a class via reflection. However I'm beginning to think that you're asking about defining new classes through at runtime. If so, then reflection won't help you here - you'd need to invoke a compiler programatically, which I believe can be done but I'm not 100% on the details. I think you'd also have to go through some hoops to get the ClassLoader to pick up your new class too.
You can create the source code string and compile it to an class file using Janino.
As people have already mentioned, there's no way of creating new classes at runtime using reflection. One library that I know is used by different mocking libraries and the likes is cglib.
you can use javassist. here is sudo code
javassist.ClassPool pool = new ClassPool(true);
CtClass bclass = pool.makeClass("brandnewclass);
bclass.addConstructor(CtNewConstructor.defaultConstructor(bclass));
CtClass[] fieldclasses = new CtClass[fields.length];
CtClass serClass = pool.get(Serializable.class.getName());
bclass.addInterface(serClass);
Class clazz = pool.loadClass("className");
obj = clazz.newInstance();
Use reflection to extract values from an existing class and assign values to new class.
hope this helps.
Gopi