Making the inner class of a generic class extend Throwable [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why doesn’t Java allow generic subclasses of Throwable?
I'm trying to make a regular RuntimeException inside a generic class like this:
public class SomeGenericClass<SomeType> {
public class SomeInternalException extends RuntimeException {
[...]
}
[...]
}
This piece of code gives me an error on the word RuntimeException saying The generic class SomeGenericClass<SomeType>.SomeInternalException may not subclass java.lang.Throwable.
What has this RuntimeException to do with my class being generic?

Java doesn't allow generic subclasses of Throwable. And, a nonstatic inner class is effectively parameterized by the type parameters of its outerclass (See Oracle JDK Bug 5086027). For instance, in your example, instances of your innerclass have types of form SomeGenericClass<T>.SomeInternalException. So, Java doesn't allow the static inner class of a generic class to extend Throwable.
A workaround would be to make SomeInternalException a static inner class. This is because if the innerclass is static its type won't be generic, i.e., SomeGenericClass.SomeInternalException.
public class SomeGenericClass<SomeType> {
public static class SomeInternalException extends RuntimeException {
[...]
}
[...]
}

Related

Inner static vs non static exception class in Java [duplicate]

This question already has an answer here:
Making the inner class of a generic class extend Throwable [duplicate]
(1 answer)
Closed 3 years ago.
I did notice a weird behaviour about the static and non-static inner exception classes.
For example the below code will not compile:
public class MyClass<T> {
private class MyInnerException extends Exception { // won't compile
..
}
}
But the below code will compile:
public class MyClass<T> {
private static class MyInnerException extends Exception { // will compile
..
}
}
Why is this behaving this way?
One thing is for sure that we cannot have Generic exceptions due to type erasure but then the above is not a Generic exception class but it is inside the Generic class. But if it is static it is allowed but if it is non-static it is not allowed?
Follow up question, is generic exception not allowed just because of the type erasure feature of Generic like it mentioned here:
https://www.mscharhag.com/java/java-exceptions-and-generic-types
Or there is some other reason to it?
One thing is for sure that we cannot have Generic exceptions due to type erasure but then the above is not a Generic exception class but it is inside the Generic class.
Your inner class (the first snippet) is a generic class, since its enclosing class is a generic class, and the enclosing class is part of the inner class. You cannot create an instance of an inner class without a corresponding instance of the enclosing class.
As to why generic classes cannot extend Exception:
It is a compile-time error if a generic class is a direct or indirect subclass of Throwable (§11.1.1).
This restriction is needed since the catch mechanism of the Java Virtual Machine works only with non-generic classes.
(JLS 8.1.2)
i.e. catch clauses cannot distinguish between MyClass<String>.MyInnerException and MyClass<Integer>.MyInnerException, and therefore generic exception classes are not allowed.

What does static in front of nested interface mean? [duplicate]

This question already has answers here:
Why would a static nested interface be used in Java?
(11 answers)
Closed 4 years ago.
I would think this is easily googleable question, but I found nothing. In the following code:
public class ParentClass {
public static interface InterfaceStatic {
}
public interface InterfaceNotStatic
{
}
}
Can you describe the difference between InterfaceNotStatic and InterfaceStatic? I know what the same syntax means for nested classes, but since interfaces hold no value, the purpose of static here eludes me.
Both declarations are the same. The static modifier is redundant in this case.
A member interface is implicitly static (§9.1.1). It is permitted for the declaration of a member interface to redundantly specify the static modifier.
(quote from JLS 8.5.1. Static Member Type Declarations)
Static inner interface and inner interface is the same, all access rules are the same as with inner static class. So inner interface can be accessible only if you have access to its parent class/interface. In case below you will have access to interface B only from package of interface A, because A has default access modifier. BTW: interface B could be static or not.

Block an interface to be extended [duplicate]

This question already has answers here:
Final interface in Java?
(10 answers)
Closed 6 years ago.
As since in a class I can do:
public final class Foo{}
wich means no more classes can extends that Foo class... e.g. String class is final, so no custom class can extends the class String.
How can I prevent to do the same with an interface?
If I do
public interface ISome{
void fly();
}
I would like to allow that
class A implements ISome {}
but block that
public interface IHouse extends ISome{
void fly();
}
doing this
public final interface ISome{}
makes no sense... and will bring a compile error like:
Illegal modifier for the interface
You can't.
Supposedly the Java designers didn't think there would ever be an appropriate use case for this: if you don't want an interface to be extended then really you ought to declare those functions directly in a concrete class.
That said, you can achieve this in C++ as in this language an interface is more of a convention - consisting of only pure virtual functions, and you can enforce non-extensibility with techniques such as friendship.

Compiler Error when Interface within Inner Class

I want to declare an interface inside an inner class, which shows compiler error message "inner classes cannot have static declarations".
public class Apple {
//...
public class InnerApple{
//...
public interface InnerInterface{
//Error: inner classes cannot have static declarations
}
}
}
Does it mean interface is actually static in Java?
I'm using Java 1.7. Thanks!!
An interface is always static - in a sense that there cannot be any dependency to another instance.
Having two levels of inner declarations is quite uncommon, but if it is intended I would expect that at least InnerApple is static:
public class Apple {
public static class InnerApple{
public interface InnerInterface{
//this does not cause an error
}
}
}
In most cases the keyword static of inner classes is omitted. If so this class may contain dependencies to a surrounding instance (and not only to the class as static inner classes do).
Yes, member interfaces are implicitly static. Section 8.5.1 of the JLS states:
A member interface is implicitly static (§9.1.1).
For it not to be static, the interface must be top-level, with no enclosing class or interface.

Is the object of an abstract class an anonymous inner class? [duplicate]

This question already has answers here:
Can we instantiate an abstract class?
(16 answers)
Closed 9 years ago.
When I create the object of an Abstract class, I have to do like this just like an interface.
AbstractClass abstractClass = new AbstractClass() {
#Override
public void abstractMethod() {
}
};
Does this mean that the object of AbstractClass is an anonymous inner class object?
AbstractClass abstractClass = new AbstractClass() {
#Override
public void abstractMethod() {
}
};
This block of code means that you are creating an anonymous class which extends AbstractClass. You can also use the same notation for an interface also.
SomeInterface someImplementingClass = new SomeInterface(){/*some code here*/};
This means you are creating a class that implements SomeInterface.
Note that there are certain limitation when you are creating an anonymous class. As and anonymous class is already extending the parent type, you cannot make it extend another class as in java you can extend only on class.
This code will help understand concept of overriding methods in anonymous classes
class Anonymous {
public void someMethod(){
System.out.println("This is from Anonymous");
}
}
class TestAnonymous{
// this is the reference of superclass
Anonymous a = new Anonymous(){ // anonymous class definition starts here
public void someMethod(){
System.out.println("This is in the subclass of Anonymous");
}
public void anotherMethod(){
System.out.println("This is in the another method from subclass that is not in suprerclass");
}
}; // and class ends here
public static void main(String [] args){
TestAnonymous ta = new TestAnonymous();
ta.a.someMethod();
// ta.a.anotherMethod(); commented because this does not compile
// for the obvious reason that we are using the superclass reference and it
// cannot access the method in the subclass that is not in superclass
}
}
This outputs
This is in the subclass of Anonymous
Remember that anotherMethod is implemented in implemented in the subclass that is created as anonymous class. and a is the reference variable of type Anonymous i.e. superclass of the anonymous class. So the statement ta.a.anotherMethod(); gives compiler error as anotherMethod() is not available in Anonymous.
An object is not a class object (in this context). It is derived from a class. In Java there is a difference between classes and objects, as compared to e.g. prototype based languages (e.g. JavaScript) where this difference does not exist.
In your example you create an anonymous class, create an object of that anonymous class and assign it to a variable; all in one step.
Anonymous classes are always inner classes: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9.5
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.3
One fundamental properties of attract classes is the fact that there could be no direct instance of this type. Only classes that implement the complete interface of an class can be instantiated.
In order to create an object you need a non abstract class first, by extending the abstract class.
Abstract classes does not have any instances (objects of it's type). I recommend Mavia to take a look at following link for clearness:
http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
You cannot create an object of an abstract class. They are non-instantiable. What you are doing when you do this is creating a sort of dynamic subclass object, and instantiating that (at the same time). More or less, yes, you can create it the same way as an interface. See this answer for more information.
In fact here you create both: an anonymous inner class, that extends AbstractClass as well as an instance of this anonyomous class, the object. You do not and cannot create an instance of AbstractClass.
Also you declare a variable named abstractClass that has the Type AbstractClass. Inside this variable you store a newly created instance of your newly defined subclass of AbstractClass.
EDIT: You can of course not reuse the anonymous inner class, since it is anonymous, and the only place where an instance of it can be created or rather is created is right here.
Here might be a loop or function in which case you would be able to create many instances of this anonymous inner class. But it would still be only this piece of code where instances are created.

Categories