I have a ClassA that is being used my many components and libraries in various areas of a project.
Now I need to add an extra member to this class but since it will not be needed/used by other areas it does not feel proper to extend the class.
If I add the member to ClassA instead of extending would I have any issues? Would everything need to be rebuild?
Adding a new member preserves binary compatibility, see also Chapter 13. Binary Compatibility of the Java Language specification.
Obviously you need to rebuild the modified class, but not classes which are using the modified one.
Unless your existing contacts and interactions between ClassA and other classes BREAK, there should be no issue. But if you change signature of a method that is used by other classes you could get a runtime error while locating the old version of method as it does not exist anymore.
If you change your Class A, obviously a rebuild is necessary. To minimize the impact you can extend the class A and use the subclass for your work. The other components and libraries will continue to keep using your Class A, while your code should now refer to the sublcass which has the added member.
Again, it depends on how you define your objects.
Related
My Java library is made of a few sub-packages (com.example.lib.api, com.example.lib.imp, com.example.lib.util,...).
The classes in api use classes A and B from imp. The classes in imp use class C in util.
I am forced to make A, B and C public, but I don't want them to be exposed to users of my library. Not hiding anything, my library is open source, but minimal APIs are simpler to understand.
Is there a way around it?
In Java 9 you will be able to control which packages are exported from a JAR. This way you can make them public, but not available to anyone else.
For now you can't control this. You either put everything in one package or rely on the documentation to make it clear they should not be used. e.g. jdk.internal assumes no one should use these except the JDK.
You cannot use a private class in any other package . Instead the class can be made public and the methods and variables can be made protected . So in this case the classes can be extended where they need and the contents in the class can be accessed only by the sub classes which extended it.
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.
Is it really impossible to hide some classes in a jar file?
I wanted not to allow direct instantiation of the classes to keep it more flexible. Only the factory (or a facade) should be visible of this jar.
Is there any other way than solve this problem than creating two projects?
(Two projects: the first one contains the classes (implementation) and the other one references to the first one and contains the factory; later only the second one will be referenced)
I'm understanding you're not looking to hide the actual classes, just prevent their construction outside a factory class. This I think can be quite easily achieved by using package private (default) visibility in the class constructors. The only limitation is that you'll need to have the classes and the factory in the same package so in a medium to large codebase things may get unnecessarily complex.
If I understand your question correctly, you would like to make sure that users of your library are forced to use your factory to instantiate their objects rather than using the constructors themselves.
As I see it there are two possibilities, one of which is silly but usable in few, specific cases, and the other one is the most practical and probably most commonly used way of doing it.
You could make all your classes into
private inner classes of the
factory. This would work if you had
one factory per class, but is hardly
workable if you have a lot of
different classes being managed
through one factory.
You could use the protected access modifier to
restrict access to your class
constructors. This is common
practice when using the factory
pattern.
I think you will have either compiler failure or warning if your public factory method try to return something which is "hidden".
No, you can not hide a public class without reimplementing your own ClassLoader or using OSGi or anything similar.
What you can do is to separate interface api from the implementation, e.g. have one project which contains only the interfaces and another porject which contains the implmentations. However, you still cannot hide the implementation classes.
Obfuscation can help you somehow.
With standard classloaders and plain old jar files, this is not possible. OSGi has this concept of making visible only some packages to another bundle(i.e. separation of public api and internal implementation).
If you are using eclipse, you may enforce such rules with this
If I understand you correctly when you say "not to allow direct instantiation of the classes to keep it more flexible", a properly executed facade pattern will handle this.
Restrict the constructors of all the classes you want to hide to package scope. Open the facade class to public scope.
http://mindprod.com/jgloss/packagescope.html
"If you have a variable or method in
your class that you don’t want clients
of your class directly accessing,
don’t give it a public, protected or
private declaration. Due to an
oversight in the design of Java, you
can’t explicitly declare the default
“package” accessibility. Other members
of the package will be able to see it,
but classes outside the package that
inherit from yours, won’t. The
protected accessibility attribute
offers slightly more visibibily. A
protected method is visible to
inheriting classes, even not part of
the same package. A package scope
(default) method is not. That is the
only difference between protected and
package scope. "
There are two solutions to your question that don't involve keeping all classes in the same package.
The first is to use the Friend Accessor/Friend Package pattern described in (Practical API Design, Tulach 2008).
The second is to use OSGi. There is an article here explaining how OSGi accomplishes this.
Related Questions: 1, 2, 3, and 4.
You can do such magics with a custom class loader but:
the correct separation will be available only in a project staffed with your class loader;
it's really doubtful that the effort to create such loader is worthy.
In such situations I would do something similar to what we may see in the standard Java. E.g.you see javax.xml.stream.XMLInputFactory but somewhere you have com.sun.xml.internal.stream.XMLInputFactoryImpl. It is perfectly compilable if you write:
new com.sun.xml.internal.stream.XMLInputFactoryImpl()
though you will hardly do it :-) With a system property you may control the actual implementation that is being loaded. To me such approach is fine in many situations.
I hope I have understood your question correctly ;)
Cheers!
Here's something that's got me a bit stumped but intrigued all the same. In my Android game I have various Levels that extend the superclass Level. What I am trying to do is build a levelDirectory (based on the Singleton DP) that essentially is an object that has a HashMap object within it that stores all the Level subclasses. Here is my question:
We're all familiar with the enhanced for loop, but how can I write something that would be the equivalent of
for(Level l : An Array Of Every Level Subclass In My Project that is an Extension of the Level Superclass){
HashMap.put(l.name, l);
}
I am trying to build a system that can dynamically update itself when I add more and more level subclasses. I know having a method in Level that submitted itself to the static Directory and was called in the Level's constructor is an option, But I'm just wondering whether there is a way of doing what I said above in that enhanced for loop?
Many thanks
The question itself is wrong. You cannot loop over List ("Every Level Subclass In My Project") and get instances of Level. l should be Class.
From the context, I think you meant "every instance of every Level subclass". No, it is not possible - a virtual machine is not and should not be a database. You cannot just query for objects, you have to manage references in your code (but that you already knew that - your constructor solution will work).
Option 1:
Lately I had to solve a similar problem within JavaSE. I'm using the Google Reflections Library for that:
http://code.google.com/p/reflections/
However I'm not sure if it can run with Android. I think it's worth to give it a try, since it's quite easy to use. In your case you would do something like:
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends Level>> subTypes = reflections.getSubTypesOf(Level.class);
That would give you a Set (subTypes) to iterate on and put it in the HashMap.
Option 2:
You could maybe use custom annotations to annotate your Level classes, for example:
#Level public class MyCustomLevel {}
Then use a custom annotation processor which implements AbstractProcessor to process the annotation at compile time. Implement the process method to find all classes annotated with your #Level annotation. Now you can write the full names of the found classes to a property file in your META-INF dir. From your application you can read this property file and instantiate the classes using reflection.
If you're trying to dynamically fetch the list of all classes that extend Level at runtime, that's not really possible, I'm afraid. Have a look at this thread: How do you find all subclasses of a given class in Java?
I think you might want to make the level an interface and then check if it's an interface.
In its most common form, an interface is a group of related methods with empty bodies. A bicycle's behavior, if specified as an interface, might appear as follows:
interface Bicycle {
void changeCadence(int newValue); // wheel revolutions per minute
void changeGear(int newValue);
void speedUp(int increment);
void applyBrakes(int decrement);
}
To implement this interface, the name of your class would change (to a particular brand of bicycle, for example, such as ACMEBicycle), and you'd use the implements keyword in the class declaration:
class ACMEBicycle implements Bicycle {
// remainder of this class implemented as before
}
Implementing an interface allows a class to become more formal about the behavior it promises to provide. Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler. If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile.
I think standard way in the "spirit" of java is the service provider pattern.
Add a declaration file in the META-INF/services of the "plugin" jar and use java.util.ServiceLoader (http://developer.android.com/reference/java/util/ServiceLoader.html) to enumerate your providers.
Don't know much about Android but sounds like Reflection might help here, so what do you know about reflection in Java?
EDIT
Didn't know you had to limit yourself to loaded levels. That being the case you would want to do your tracking on every instance as it is created pretty much like you proposed in your question.
My idea involved parsing all the directories of a project looking for subclasses - it could be done once at the start of program execution but it would list levels that may never get instantiated...
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