I'm experiment with Generic Classes, and I've run into a hurdle which I cannot overcome. In short, I'm encountering an error which I do not understand why it is being thrown: InstantiationException
In the documentation it defines this exception as:
Thrown when an application tries to create an instance of a class using the newInstance method in class Class, but the specified class object cannot be instantiated because it is an interface or is an abstract class.
Now the problem that has me scratching my head is that I do not use the abstract or interface keyword. I've also heard that it could be due to not having a default constructor (which I have). Just to be sure, I reduced my code to the minimal possible, but still gives an error:
package Sandbox;
public class Sandbox {
public static void main(String[] args) {
Sandbox box = new Sandbox();
}
public Sandbox() {
aMethod(subThread.class);
}
public void aMethod(Class<? extends superThread> type) {
try {
System.out.println("isInterface: "+type.isInterface());
System.out.println("isAssignableFrom of subThread: "+type.isAssignableFrom(subThread.class));
superThread t = type.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private class superThread { // implements Runnable {
public superThread() {}
public void run() {}
}
private class subThread extends superThread {
public subThread() {
super();
}
public void run() {
// more stuff
}
}
}
The Output:
isInterface: false
isAssignableFrom of subThread: true
java.lang.InstantiationException: Sandbox.Sandbox$subThread
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at Sandbox.Sandbox.aMethod(Sandbox.java:20)
at Sandbox.Sandbox.<init>(Sandbox.java:11)
at Sandbox.Sandbox.main(Sandbox.java:7)
I'm sure it's quite simple, but I cannot figure this one out. I've tried several things, but nothing has helped. Any and all help is appreciated.
Thanks,
Jon
It's because your inner classes are private. Simple fix:
public static class superThread { // implements Runnable {
public superThread() {}
public void run() {}
}
public static class subThread extends superThread {
public subThread() {
super();
}
public void run() {
// more stuff
}
}
The reasoning is because Class.newInstance must be able to access the constructor for the class you want to create.
Since the class is private, it's not accessible. Also, in order to access a non-static inner class, you essentially have to have an existing instance of the outer class (Sandbox), which newInstance doesn't have. As a result, having either public non-static or private static wouldn't work.
After zjagannatha pointed to the real problem, I also found a fix to my own code that allows me to keep the methods as non-static... essentially I discovered that even though the constructor had zero parameters, Constructor treated it as if it had one. I got it to list the parameter and found it odd that it needed a Sandbox class (I assume the one I'm currently working in) To allow a non-static class, I would need to change my newInstance code to this:
type.getConstructor(this.getClass()).newInstance(this);
and this works as well
Related
In Java, I'm trying to override a class coming from a library. One of the constructors of the class is private and thus I'm not able to call it from my class. Is there a way to work around this (reflection?)?
public class LibraryClass extends ProtectedLibraryClass {
public LibraryClass() {
super();
}
private LibraryClass(Boolean useFeature) {
super(useFeature);
}
// Other methods
}
public class MyClass extends LibraryClass {
public MyClass() {
super();
}
private MyClass(Boolean useFeature) {
super(useFeature); // <-- This line throws exception as super class constructor is private
}
// Override other methods
}
I can't just call super() and then set useFeature flag as useFeature flag is final in protectedLibraryClass and is set only through it's constructor.
they made it for a reason but you can use reflection in java to create object from this class even if it private
here is example :
public static void main(String[] args) {
LibraryClass copy = null;
try {
Constructor[] constructors = LibraryClass.class.getDeclaredConstructors();
for (Constructor constructor : constructors) {
constructor.setAccessible(true);
copy = (LibraryClass) constructor.newInstance();
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
I don't think this is possible, looking at this post and these docs. What you could possibly do is place the two (or however many) class files into their own package and then use the protected access modifier so that the constructor is only usable within the package. If you only place classes that inherit from the LibraryClass class it would have the same effect as making the constructor private as indicated above.
I have two classes inheriting from java.lang.Exception. They both have a method with the same signature void a(){...}. They both can be thrown in a code block. If I do:
catch (SubException1 | SubException2 e)
{
e.a();
}
Then it won't compile because method a() does not belong to Exception. Is it a Java language flaw? How should I design my code properly to prevent code redundancy?
When you catch multiple exception types in a single catch statement the inferred type of the caught exception is the greatest common denominator of those classes. In your case, the greatest common denominator is Exception, which doesn't have the method void a(). In order to make it accessible to the catch block you could either extract it to a common base class, or (arguably) more elegantly, define it in an interface that both classes implement:
public interface SomeExceptionInterface {
void a();
}
public class SomeException extends Exception implements SomeExceptionInterface {
// Implementation...
}
public class SomeException2 extends Exception implements SomeExceptionInterface {
// Implementation...
}
If you need to access a method called a(), you need a type that provides that method. A simple solution could be:
public class AbstractSubException extends Exception {
public abstract void a();
}
public class SubException1 extends AbstractSubException {
#Override public void a() { ... }
}
public class SubException2 extends AbstractSubException {
#Override public void a() { ... }
}
Then you can catch the way you did or (somewhat simpler):
catch (AbstractSubException e) {
e.a();
}
Maybe the code for the method a is the same in all sub classes. Then you can make it concrete and put the code into the parent class.
I'm learning about inheritance and am working with this simple program that has has a superclass and a subclass as shown below. My question isn't specific to this program; however, this is where I've first seen this happen so I'm using it as an example for a more general conceptual question. Why does simply instantiating the class run the constructors and output the contents? My previous understanding was that instantiating the class simply creates the object but it wont do anything.
SuperClass1.java
public class SuperClass1 {
public SuperClass1(){
System.out.println("This is the superclass constructor.");
}
}
SubClass2.java
public class SubClass2 extends SuperClass1
{
public SubClass2()
{
System.out.println("This is the subclass constructor.");
}
}
Main.java
public class Main {
public static void main(String[] args)
{
SubClass2 obj1 = new SubClass2(); // why should this print something?
}
}
Output
This is the superclass constructor.
This is the subclass constructor.
First of all, instantiating an object means calling (and executing) the constructor, that is what it is for.
So, this:
SubClass2 newInstance = <createNewInstance>;
newInstance.<init()>;
is both done by the constructor call new SubClass2() in Java. There is no separation between "constructing" the object and "initialising" its properties.
Furthermore, if you do not explicitly call another constructor of a super class the default constructor (the one without arguments) is automatically called first thing when creating an object of a class. So instantiating an object of the subclass calls the superclass contructor (which prints the first line), and then prints the second line itself.
More in detail, the subclass looks like this behind the scene:
public class SubClass2 extends SuperClass1
{
public SubClass2()
{
super(); // calls the superclass constructor
System.out.println("This is the subclass constructor.");
}
}
Because the constructor you call includes a print statement.
You call the constructor method SubClass2() which has a print statement in it.
The statements are not printed because the class ist loaded, but because an object of that class in instantiated and the constructors are called:
That a class can be loaded without using constructor is demonstrated by the following code:
public class Test {
public static void main(String[] args) {
try {
Class.forName("Test$Inner");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
static class Inner {
static {
System.out.println("static initializer");
}
public Inner() {
System.out.println("inner ctor");
}
}
}
running that program shows that only the static class initializer is called and no constructor.
I have a number of classes that define a method, and I want to execute some code (say, some "prologue" and "epilogue") around that method:
public interface Thing {
public void stuff();
public void callStuff();
}
public abstract class Something implements Thing {
public abstract void stuff();
public void callStuff() {
... // common prologue
//try {
stuff();
//} finally {
... // common epilogue
//}
}
}
public class A extends Something {
public void stuff() { ... }
}
public class B extends Something {
public void stuff() { ... }
}
public class Wrapper extends Thing {
private Thing t;
Wrapper(Thing thing) { t = thing; }
public void stuff() { t.stuff(); }
public void callStuff() { t.callStuff(); }
}
// Use:
Something s = ...;
s.callStuff();
You see that the idea is that subclasses will redefine stuff() while the clients will invoke callStuff(). Nevertheless, in some rare cases one has to call stuff(), see Wrapper above.
Something like that we see in the Thread class (since JDK 1.0), child classes redefine run() but the clients invoke start().
How do I prevent clients from calling stuff() directly?
EDIT
protected does not work here because the "clients" really are children of Something coded by another team. #Deprecated would work, but stuff() is not really deprecated, and everyone knows what "deprecated" is, so I cannot redefine the meaning of #Deprecated.
Ideally, the compilation should fail unless an explicit directive is given to ignore the problem.
This might not be possible but I am trying to create a constructor that only classes that share a super class can access, almost a reverse logic of the protected modifier. I assume there is no modifier to accomplish this directly, but knowing what I am trying to accomplish, any suggestions?
public Account extends SomeEntity {
//default public
public Account() {
}
// I am wanting this constructor to be only available to sibling classes.
// (those that share the same super class )
<modifier> Account(Element accountElement) {
}
}
public Accounts extends SomeEntity {
private List<Account> accountList;
//default public
public Accounts() {
Account newAcct = new Account(element);
//looped loading up Generic list of Account
this.accountList.add(newAcct);
}
I am working with RESTful web services and building the Objects out of XML responses, the problem is if I GET a listing of accounts, to build that into a list of Account Objects I would have to query the web service for each individual account even though I already have the information, and that seems entirely inefficient.
BUT
I don't want to give a general user, of the API I'm building, to be able to instantiate an Account Object this way. (With an Element)
There is no language construct like this. Package (=default) access is the only Java mechanism in town, as of 1.6.
I'm sure you could do nasty things with the stack, but I wouldn't recommend them.
I'd take a look at the factory pattern. You can probably play games with the access modifiers of the factory method(s) to get something close to what you want. You might also be able to play with reflection inside the factory method to get something closer to what you want than what package access gets you.
Sorry but I still don't get the point of this design. If a method is added to a class, its implementation will probably use private data to this class only, and therefore no guarantee can be made to 'sibling' classes that this data is also available for them. In other words, if your wish was granted, how would you guarantee that constructor Account(Object arg0) implementation won't use private data to Account class? (and therefore invisible to Accounts class)
It seems to me like you desire your code to provide the same interface for a single account and a list of accounts - extending SomeEntity class. That can be accomplished more elegantly with a composite pattern.
http://en.wikipedia.org/wiki/Composite_pattern
if your intent however is to provide a custom constructor that only subclasses will use, why not declare the custom constructor in SomeEntity and making this class abstract?
also, remember you can do this:
public Account() {
this(new arg0());
}
Account(Object arg0) {
}
Not sure if this helps, though.
There is a way to emulate the C++'s friend feature, and thus achieve the result you want.
Warning: This is a contrived technique that should be used only if you have no other solution!
Since no modifier does what you want in this case, the trick is to move the access restriction to another place, where modifiers apply. To do that, add a key parameter to the constructor. That key is of a class that can only be instantiated by the allowed "sibling" classes, i.e. by the subclasses of a given class.
The restriction is thus moved to the common superclass, where restraining the creation of the key is possible with the usual modifiers.
Here is an example:
public class CommonSuperClass {
public static final class Key {
private Key() {}
}
// This is the only way to create a key, and it's protected
protected final Key createKey() {
return new Key();
}
}
public class Account {
// The restricted constructor can even be public
public Account(Key key) {
// Everybody can try with null, but we're not that stupid
// Of course any RuntimeException can be thrown instead
if (key == null) throw new UnsupportedOperationException();
}
}
public class AllowedSibling extends CommonSuperClass {
public void foo() {
// I'm allowed
new Account(this.createKey());
}
}
public class DeniedClass {
public void foo() {
// This doesn't compile
new Account(new Key());
// This will throw an exception
new Account(null);
}
}
This is a very strange requisite, and I think no access modifier can do what you want. Anyway, I recommend that you just make the constructors public and document them as "for internal use only".
If you really need to limit access you can use this wordy solution:
public class Base {
protected interface Factory {
Base getInstance(Element e);
}
private static Map<Class<?>, Factory> registry = new HashMap<Class<?>, Factory>();
protected static void register(Class<?> c, Factory f) { registry.put(c, f); }
protected static <T extends Base> T create(Class<T> c, Element e) {
return (T) registry.get(c).getInstance(e);
}
}
public class Derived1 extends Base {
protected Derived1(Element e) { }
private static class Derived1Factory implements Factory {
public Derived1 getInstance(Element e) {
return new Derived1(e);
}
}
static {
register(Derived1.class, new Derived1Factory());
}
}
public class Derived2 extends Base {
protected Derived2(Element e) { }
private static class Derived2Factory implements Factory {
public Derived2 getInstance(Element e) {
return new Derived2(e);
}
}
static {
register(Derived2.class, new Derived2Factory());
}
public void method() {
Element e = null;
...
// Put some element in e
...
// This is what you were trying to do
Derived1 d1 = create(Derived1.class, e);
}
}
public class SomeEntity
protected void init(Element accountElement) {}
public class Account extends SomeEntity
public Account()
....
protected void init(Element accountElement)
....
public class Accounts extends SomeEntity
Account newAcct = new Account();
newAcct.init(element);
Here's what I would try (I have not tested this method):
<modifier> Account(Object arg) {
if (!super.getClass().isAssignableFrom(this.getClass())) {
throw new AssertionError("This constructor is only available to super classes.");
} else {
// Continue...
}
}