I'm dealing with a contractor's code. For whatever reason he has made a series of "constants" files that are all interfaces. They look like this:
interface SomeTypeConsts {
public static class SomeSubTypeA {
public static final String CONSTANT_A = "foo";
public static final String CONSTANT_B = "bar";
}
public static class SomeSubTypeB {
public static final String CONSTANT_A = "baz";
}
}
and so forth. There are no unimplemented/abstract methods, the files just contain nested classes some arbitrary level deep, and static final Strings for the constants. I cannot modify the contractor's code at this time.
I'm writing a test framework and I need an instance of one of these constants interfaces. All of them follow the above pattern, but my method needs to support all of them and not just one in specific.
I tried instantiating the interface using Reflection like this:
clazz.newInstance() // where clazz is Class<SomeTypeConsts>
But it threw a java.lang.InstantiationException.
All of the questions here on SO say that you need to implement the interface first, then use that instance. And if I knew ahead of time which const interface it was, I could easily do SomeTypeConsts consts = new SomeTypeConsts(){};. But I haven't been able to figure out how to do this with reflection, when all I have to work with is the Class<SomeTypeConst>.
Given an interface Class reference, with no abstract methods to be overwritten/implemented, how can I instantiate an instance of it using reflection?
You could do this using a JDK proxy for the interface, but it would be entirely pointless: If all you're doing is accessing static members, all of that is resolved without reference to any actual instance of the type in question, either at compile-time (far preferable) or at runtime with some approach like enumerating the fields and filtering on the static ones.
From the language spec (emphasis mine):
This type has no instance variables, and typically declares one or more abstract methods; otherwise unrelated classes can implement the interface by providing implementations for its abstract methods. Interfaces may not be directly instantiated.
And, from the Javadoc of Class.newInstance():
[throws] InstantiationException - if this Class represents an abstract class, an interface, an array class, a primitive type, or void; or if the class has no nullary constructor; or if the instantiation fails for some other reason.
You can't instantiate an interface. You can only instantiate (non-abstract) classes which implement it.
No. You cannot do that. Interfaces by definition are not instantiable.
What you need is a mock object. Not reflection
Related
My goal is to create an abstract class whose static methods have to be implemented, but I was having some issues due to static methods not being able to be made abstract.
This is the solution I came up with:
public abstract class CombinedMethod {
public static String computeMethodBody() throws
CannotCompileException {
throw new NotImplementedException();
}
public static ArrayList<CtMethod> sortSelectedMethods() {
throw new NotImplementedException();
}
}
I'm making this post because I couldn't find any equivalent answer, which left me wondering if this is idiomatic in Java.
Edit to add use case:
I want to create several classes that must all implement both computeMethodBody and sortSelectedMethods.
My solution adds structure and semantic meaning to the code, compared to, for example, creating documentation explaining how to create equivalent classes.
I am aware of why overriding static methods doesn't make sense in Java and that I'm just hiding them. As I said there's no other answer exemplifying this use case, but there's plenty discussing the concept.
Edit to add more details about the project:
The goal here is to implement some features of Common Lisp's method combination, using annotations as modifiers.
To name an example, suppose Class2 inherits from Class1:
public class Class1 {
...
#Combination("+")
public int myValue()
{
System.out.println("In myValue of Class1");
return 1;
}
}
public class Class2 extends Class1 {
...
#Combination("+")
public int myValue()
{
System.out.println("In myValue of Class2");
return 2;
}
}
Since they're both annotated with "+", I want to change the behaviour of this method at load time, so that Class2's effective method will be something behaviourally equivalent to:
#Combination("+")
public int myValue()
{
System.out.println("In myValue of Class2");
System.out.println("In myValue of Class1");
return 2 + 1;
}
To do so, I employed Javassist to compute a new effective method. Fortunately, I was able to generalize my architecture, so adding new functionality entails creating a static method and calling it inside a new switch case statement:
String computeEffectiveMethodBody(String annotationValue, CtClass ctClass, ArrayList<CtMethod> sortedSelectedMethods) throws CannotCompileException {
switch (annotationValue) {
case "min":
return CombinedMin.computeMethodBody(ctClass, sortedSelectedMethods);
case "max":
return CombinedMax.computeMethodBody(ctClass, sortedSelectedMethods);
case "+":
return CombinedAddition.computeMethodBody(ctClass, sortedSelectedMethods);
case "and":
return CombinedAnd.computeMethodBody(ctClass, sortedSelectedMethods);
case "or":
return CombinedOr.computeMethodBody(ctClass, sortedSelectedMethods);
default:
throw new RuntimeException("Invalid annotation");
}
}
The way I choose to segregate it was by creating a package called combinedMethods. Inside it, there's the parent function CombinedMethod and another subpackage called methods where all of the extensions with the actual static methods are kept.
Thank you #AasmundEldhuset for your interest, I'm always looking for the best way to architecture my software, even though I haven't learned it formally yet.
enforce implementation of inherited static methods in Java?
Java Language Specification says:
A class does not inherit private or static methods from its superinterface types.
Static methods are also called class methods. They are bound to a class and don't require an instance of the class in order to be invoked.
static and abstract is an illegal combination of modifiers because static methods are completely self-contained and always have an implementation.
You can not inherit static methods and as subsequence the concept of overriding is not applicable to them. And since a subclass can not override a parent's static method, abstract static method doesn't make sense because it can not be implemented.
A class method can be hidden by a method from a subclass with the same signature.
A quote from JLS:
A class (static) method that is hidden can be invoked by using a reference whose type is the type of the class that actually contains the declaration of the method. In this respect, hiding of static methods is different from overriding of instance methods.
I.e. hidden version can be invoked only on a child class or instance, conversely to the overridden method which can be invoked on the instance on of parent class or on the instance on of child class.
In other words, you can't obtain polymorphic behavior with static methods.
UPDATE
I want to create several classes that must all implement both computeMethodBody and sortSelectedMethods
So you want these two static methods with the same signature to be present in a couple of classes. And that's totally fine. But you don't need a parent abstract class for that because there's no useful code in it if both its method will be hidden.
creating documentation explaining how to create equivalent classes
Inheritance in Object-Oriented Programming isn't used for documentary purposes. The child should be capable to replace its parent in any use-cases, as Liskov substitution principle suggests.
The problem is that there are no use-cases for such a parent class. combinedMethod class isn't designed for inheritance (BTW, it's not a very informative name and by convention names of classes and interfaces should start with a capital letter).
You are misusing inheritance. If you need to provide the end-users of your classes with some additional information, there are other ways to do that:
The very first mean is a self-documenting code. Use clear, concise and self-explanatory names for your methods and classes.
Since Java 5 metadata can be provided with annotations.
In earlier versions, marker-interfaces were used for that purpose. But classes were never utilized for that.
Another thing that you need to understand is that although inheritance is a very important and useful mechanism, it also has pitfalls and should be applied after careful consideration.
Even if your case would be more suitable to apply inheritance, it wouldn't automatically mean that inheritance is the best option.
For instance, classes IntSummaryStatistics, LongSummaryStatistics and DoubleSummaryStatistics have no parent class in the JDK, although they have common fields and behavior.
Take a look at these classes a compare with your situation when parent isn't designed to be extended and has nothing to offer to its subclasses.
If you need to provide metadata - you can create a custom annotation like #CapableOfSomething and mark your classes with it, but don't abuse inheritance instead.
Static methods are invoked on a class, independent of an instance, so if they would be abstract, how would the run-time know on which sub-class to call them?
CombinedMethod cm1 = new SubclassA(...)
CombinedMethod cm2 = new SubclassB(...)
// static method computeMethodBody is called on neither cm1 or cm2, so what implementation to choose.
String result = CombinedMethod.computeMethodBody();
In java we are not able to create an instance of an interface like this:
iJack obj = new iJack(); //iJack is an interface
However, I noticed that we can do this:
iJack obj;
What is the difference between the two?
In addition to that, I noticed that you can nest a class within an interface, how is this useful? I can not think of a practical purpose for this. Here is an example of what I am talking about:
public interface iJack {
public abstract class Jack_class {
}
}
Interfaces can not be instantiated. Only classes can. However, you can (and should) use an interface as the type of a variable.
Your line...
iJack obj;
...declares a variable of the iJack type, but it does not initialize it.
By the way, you should always use a capital letter at the beginning of an interface name.
If you define a reference variable whose type is an interface, any object you assign to it must be an instance of a class that implements the interface.
you asking what is the difference between the two. first one is wrong. you can't instantiate interface but classes that implement those interfaces. so you can't talk about differences
Reference :Using an Interface as a Type
the uses of nested classes in interface has the same purpose as the uses of nested classes in another class. that is scoping the class to the interface.
Reference :Nested class inside an interface
Ok so I know that you can't have an abstract static method, although I see this as a limitation personally. I also know that overriding static methods is useless because when I am dealing with say MyList<T extends ObjectWithId> and my object has an abstract class with a static method that gets overridden in it's subclasses, T doesn't exist at runtime so ObjectWithId's static method would be called instead of the subclass.
So here is what I have:
class PersistentList<T extends ObjectWithId> implements List<T>{
}
where ObjectWithId is:
abstract ObjectWithId{
public abstract long getId();
}
Now the issue is that my PersistentList is meant to be stored on hard disk, hence the name, and in reality will only store ids of objects it holds. Now when I want to implement the
#Override
public T get(int index) {
}
method of PersistentList, what I want is for my program to use the id it has stored for index and call a static method objectForId(long id) which would be implemented in each subclass of ObjectWithId. It can't be a instance method because there is no instance yet, the point is to load the instance from the hard disk using the id. So how should it be implemented? One option is to have ObjectWithId have a constructor ObjectWithId(long id) implemented in each subclass, but T doesn't exist at runtime so how would I instantiate it? I know I could pass Class<T> object in the constructor of PersistentList but I would prefer if the constructor did not have any arguments, but I don't think there is a way to get the class of T without explicitly passing it in right?
I hope this is a better explanation, sorry for the ambiguous question I started with.
While passing the Class<T> as a constructor argument, it does not really solves your problem. You then have access to the class, but to get access to the static method defined on the class you will have to use generics (unless somebody else knows a way to call a static method defined on a class from a Class object).
I would define a new generic interface which contains a generic method objectForID, something like
public interface ObjectRetriever<T>{
public T objectForID( long aID );
}
and adjust the constructor of the PersistentList to take such a ObjectRetriever instance as parameter. This ObjectRetriever can then be used to restore the objects based on their ID.
While it always seems easier to start out with static methods, I've found it to usually be beneficial to avoid static methods for just this reason, and to use instance methods by default.
The advantage to this is extensibility. Besides allowing for inheritance and avoiding the "limitations" you mentioned, it provides for extensibility - without needing to redesign things and change APIs later. For example, "this class does exactly what I need, but I wish I could change only this one portion of functionality". If there are static methods calling other static methods, there is no good way to do this. If all the methods are non-static - I can subclass that class and override only the portion of functionality required.
The other (somewhat-related) limitation to static methods is that they can't be used to implement interfaces.
In summary, I prefer to reserve static methods for "utility methods" where the function that they are performing is really clear-cut, and there isn't any feasible future reason why an alternative implementation would need to be provided.
I am just trying to understand why all fields defined in an Interface are implicitly static and final. The idea of keeping fields static makes sense to me as you can't have objects of an interface but why they are final (implicitly)?
Any one knows why Java designers went with making the fields in an interface static and final?
An interface is intended to specify an interaction contract, not implementation details. A developer should be able to use an implementation just by looking at the interface, and not have to look inside the class which implements it.
An interface does not allow you to create an instance of it, because you cannot specify constructors. So it cannot have instance state, although interface fields can define constants, which are implicitly static and final.
You cannot specify method bodies or initializer blocks in an interface, although since Java 8 you can specify default methods with bodies. This feature is intended to allow new methods to be added to existing interfaces without having to update all the implementations. But you still cannot execute such a method, without first creating an instance implementing the interface.
Aside: Note that you can implement an interface with an anonymous inner class:
interface Foo {
String bar();
}
class FooBar {
Foo anonymous = new Foo() {
public String bar() {
return "The Laundromat Café";
};
}
You have to provide the full implementation of the interface for the anonymous inner class to compile.
new Foo() is initializing the anonymous inner class with its default constructor.
Reason for being final
Any implementations can change value of fields if they are not defined as final. Then they would become a part of the implementation. An interface is a pure specification without any implementation.
Reason for being static
If they are static, then they belong to the interface, and not the object, nor the run-time type of the object.
There are a couple of points glossed over here:
Just because fields in an interface are implicitly static final does not mean they must be compile-time constants, or even immutable. You can define e.g.
interface I {
String TOKEN = SomeOtherClass.heavyComputation();
JButton BAD_IDEA = new JButton("hello");
}
(Beware that doing this inside an annotation definition can confuse javac, relating to the fact that the above actually compiles to a static initializer.)
Also, the reason for this restriction is more stylistic than technical, and a lot of people would like to see it be relaxed.
The fields must be static because they can't be abstract (like methods can). Because they can't be abstract, the implementers will not be able to logically provide the different implementation of the fields.
The fields must be final, I think, because the fields may be accessed by many different implementers allows they to be changeable might be problematic (as synchronization). Also to avoid it to be re-implemented (hidden).
Just my thought.
I consider the requirement that the fields be final as unduly restrictive and a mistake by the Java language designers. There are times, e.g. tree handling, when you need to set constants in the implementation which are required to perform operations on an object of the interface type. Selecting a code path on the implementing class is a kludge. The workaround which I use is to define an interface function and implement it by returning a literal:
public interface iMine {
String __ImplementationConstant();
...
}
public class AClass implements iMine {
public String __ImplementationConstant(){
return "AClass value for the Implementation Constant";
}
...
}
public class BClass implements iMine {
public String __ImplementationConstant(){
return "BClass value for the Implementation Constant";
}
...
}
However, it would be simpler, clearer and less prone to aberrant implementation to use this syntax:
public interface iMine {
String __ImplementationConstant;
...
}
public class AClass implements iMine {
public static String __ImplementationConstant =
"AClass value for the Implementation Constant";
...
}
public class BClass implements iMine {
public static String __ImplementationConstant =
"BClass value for the Implementation Constant";
...
}
Specification, contracts... The machine instruction for field access uses object address plus field offset. Since classes can implement many interfaces, there is no way to make non-final interface field to have the same offset in all classes that extend this interface. Therefore different mechanism for field access must be implemented: two memory accesses (get field offset, get field value) instead of one plus maintaining kind of virtual field table (analog of virtual method table). Guess they just didn't want to complicate jvm for functionality that can be easily simulated via existing stuff (methods).
In scala we can have fields in interfaces, though internally they are implemented as I explained above (as methods).
static:
Anything (variable or method) that is static in Java can be invoked as Classname.variablename or Classname.methodname or directly. It is not compulsory to invoke it only by using object name.
In interface, objects cannot be declared and static makes it possible to invoke variables just through class name without the need of object name.
final:
It helps to maintain a constant value for a variable as it can't be overridden in its subclasses.
This question already has answers here:
Why can't I define a static method in a Java interface?
(24 answers)
Closed 3 years ago.
There have been a few questions asked here about why you can't define static methods within interfaces, but none of them address a basic inconsistency: why can you define static fields and static inner types within an interface, but not static methods?
Static inner types perhaps aren't a fair comparison, since that's just syntactic sugar that generates a new class, but why fields but not methods?
An argument against static methods within interfaces is that it breaks the virtual table resolution strategy used by the JVM, but shouldn't that apply equally to static fields, i.e. the compiler can just inline it?
Consistency is what I desire, and Java should have either supported no statics of any form within an interface, or it should be consistent and allow them.
An official proposal has been made to allow static methods in interfaces in Java 7. This proposal is being made under Project Coin.
My personal opinion is that it's a great idea. There is no technical difficulty in implementation, and it's a very logical, reasonable thing to do. There are several proposals in Project Coin that I hope will never become part of the Java language, but this is one that could clean up a lot of APIs. For example, the Collections class has static methods for manipulating any List implementation; those could be included in the List interface.
Update: In the Java Posse Podcast #234, Joe D'arcy mentioned the proposal briefly, saying that it was "complex" and probably would not make it in under Project Coin.
Update: While they didn't make it into Project Coin for Java 7, Java 8 does support static functions in interfaces.
I'm going to go with my pet theory with this one, which is that the lack of consistency in this case is a matter of convenience rather than design or necessity, since I've heard no convincing argument that it was either of those two.
Static fields are there (a) because they were there in JDK 1.0, and many dodgy decisions were made in JDK 1.0, and (b) static final fields in interfaces are the closest thing java had to constants at the time.
Static inner classes in interfaces were allowed because that's pure syntactic sugar - the inner class isn't actually anything to do with the parent class.
So static methods aren't allowed simply because there's no compelling reason to do so; consistency isn't sufficiently compelling to change the status quo.
Of course, this could be permitted in future JLS versions without breaking anything.
There is never a point to declaring a static method in an interface. They cannot be executed by the normal call MyInterface.staticMethod(). (EDIT:Since that last sentence confused some people, calling MyClass.staticMethod() executes precisely the implementation of staticMethod on MyClass, which if MyClass is an interface cannot exist!) If you call them by specifying the implementing class MyImplementor.staticMethod() then you must know the actual class, so it is irrelevant whether the interface contains it or not.
More importantly, static methods are never overridden, and if you try to do:
MyInterface var = new MyImplementingClass();
var.staticMethod();
the rules for static say that the method defined in the declared type of var must be executed. Since this is an interface, this is impossible.
You can of course always remove the static keyword from the method. Everything will work fine. You may have to suppress some warnings if it is called from an instance method.
To answer some of the comments below, the reason you can't execute "result=MyInterface.staticMethod()" is that it would have to execute the version of the method defined in MyInterface. But there can't be a version defined in MyInterface, because it's an interface. It doesn't have code by definition.
The purpose of interfaces is to define a contract without providing an implementation. Therefore, you can't have static methods, because they'd have to have an implementation already in the interface since you can't override static methods. As to fields, only static final fields are allowed, which are, essentially, constants (in 1.5+ you can also have enums in interfaces). The constants are there to help define the interface without magic numbers.
BTW, there's no need to explicitly specify static final modifiers for fields in interfaces, because only static final fields are allowed.
This is an old thread , but this is something very important question for all. Since i noticed this today only so i am trying to explain it in cleaner way:
The main purpose of interface is to provide something that is unimplementable, so if they provide
static methods to be allowed
then you can call that method using interfaceName.staticMethodName(), but this is unimplemented method and contains nothing. So it is useless to allow static methods. Therefore they do not provide this at all.
static fields are allowed
because fields are not implementable, by implementable i mean you can not perform any logical operation in field, you can do operation on field. So you are not changing behavior of field that is why they are allowed.
Inner classes are allowed
Inner classes are allowed because after compilation different class file of the Inner class is created say InterfaceName$InnerClassName.class , so basically you are providing implementation in different entity all together but not in interface. So implementation in Inner classes is provided.
I hope this would help.
Actually sometimes there are reasons someone can benefit from static methods. They can be used as factory methods for the classes that implement the interface. For example that's the reason we have Collection interface and the Collections class in openjdk now. So there are workarounds as always - provide another class with a private constructor which will serve as a "namespace" for the static methods.
Prior to Java 5, a common usage for static fields was:
interface HtmlConstants {
static String OPEN = "<";
static String SLASH_OPEN = "</";
static String CLOSE = ">";
static String SLASH_CLOSE = " />";
static String HTML = "html";
static String BODY = "body";
...
}
public class HtmlBuilder implements HtmlConstants { // implements ?!?
public String buildHtml() {
StringBuffer sb = new StringBuffer();
sb.append(OPEN).append(HTML).append(CLOSE);
sb.append(OPEN).append(BODY).append(CLOSE);
...
sb.append(SLASH_OPEN).append(BODY).append(CLOSE);
sb.append(SLASH_OPEN).append(HTML).append(CLOSE);
return sb.toString();
}
}
This meant HtmlBuilder would not have to qualify each constant, so it could use OPEN instead of HtmlConstants.OPEN
Using implements in this way is ultimately confusing.
Now with Java 5, we have the import static syntax to achieve the same effect:
private final class HtmlConstants {
...
private HtmlConstants() { /* empty */ }
}
import static HtmlConstants.*;
public class HtmlBuilder { // no longer uses implements
...
}
There is no real reason for not having static methods in interfaces except: the Java language designers did not want it like that.
From a technical standpoint it would make sense to allow them. After all an abstract class can have them as well. I assume but did not test it, that you can "hand craft" byte code where the interface has a static method and it should imho work with no problems to call the method and/or to use the interface as usually.
I often wonder why static methods at all? They do have their uses, but package/namespace level methods would probably cover 80 of what static methods are used for.
Two main reasons spring to mind:
Static methods in Java cannot be overridden by subclasses, and this is a much bigger deal for methods than static fields. In practice, I've never even wanted to override a field in a subclass, but I override methods all the time. So having static methods prevents a class implementing the interface from supplying its own implementation of that method, which largely defeats the purpose of using an interface.
Interfaces aren't supposed to have code; that's what abstract classes are for. The whole point of an interface is to let you talk about possibly-unrelated objects which happen to all have a certain set of methods. Actually providing an implementation of those methods is outside the bounds of what interfaces are intended to be.
Static methods are tied to a class. In Java, an interface is not technically a class, it is a type, but not a class (hence, the keyword implements, and interfaces do not extend Object). Because interfaces are not classes, they cannot have static methods, because there is no actual class to attach to.
You may call InterfaceName.class to get the Class Object corresponding to the interface, but the Class class specifically states that it represents classes and interfaces in a Java application. However, the interface itself is not treated as a class, and hence you cannot attach a static method.
Only static final fields may be declared in an interface (much like methods, which are public even if you don't include the "public" keyword, static fields are "final" with or without the keyword).
These are only values, and will be copied literally wherever they are used at compile time, so you never actually "call" static fields at runtime. Having a static method would not have the same semantics, since it would involve calling an interface without an implementation, which Java does not allow.
The reason is that all methods defined in an interface are abstract whether or not you explicitly declare that modifier. An abstract static method is not an allowable combination of modifiers since static methods are not able to be overridden.
As to why interfaces allow static fields. I have a feeling that should be considered a "feature". The only possibility I can think of would be to group constants that implementations of the interface would be interested in.
I agree that consistency would have been a better approach. No static members should be allowed in an interface.
I believe that static methods can be accessed without creating an object and the interface does not allow creating an object as to restrict the programmers from using the interface methods directly rather than from its implemented class.
But if you define a static method in an interface, you can access it directly without its implementation. Thus static methods are not allowed in interfaces.
I don't think that consistency should be a concern.
Java 1.8 interface static method is visible to interface methods only, if we remove the methodSta1() method from the InterfaceExample class,
we won’t be able to use it for the InterfaceExample object. However like other static methods, we can use interface static methods using class name.
For example, a valid statement will be:
exp1.methodSta1();
So after looking below example we can say :
1) Java interface static method is part of interface, we can’t use it for implementation class objects.
2) Java interface static methods are good for providing utility methods, for example null check, collection sorting ,log etc.
3) Java interface static method helps us in providing security by not allowing implementation classes (InterfaceExample) to override them.
4) We can’t define interface static method for Object class methods, we will get compiler error as “This static method cannot hide the instance method from Object”. This is because it’s not allowed in java, since Object is the base class for all the classes and we can’t have one class level static method and another instance method with same signature.
5) We can use java interface static methods to remove utility classes such as Collections and move all of it’s static methods to the corresponding interface,
that would be easy to find and use.
public class InterfaceExample implements exp1 {
#Override
public void method() {
System.out.println("From method()");
}
public static void main(String[] args) {
new InterfaceExample().method2();
InterfaceExample.methodSta2(); // <--------------------------- would not compile
// methodSta1(); // <--------------------------- would not compile
exp1.methodSta1();
}
static void methodSta2() { // <-- it compile successfully but it can't be overridden in child classes
System.out.println("========= InterfaceExample :: from methodSta2() ======");
}
}
interface exp1 {
void method();
//protected void method1(); // <-- error
//private void method2(); // <-- error
//static void methodSta1(); // <-- error it require body in java 1.8
static void methodSta1() { // <-- it compile successfully but it can't be overridden in child classes
System.out.println("========= exp1:: from methodSta1() ======");
}
static void methodSta2() { // <-- it compile successfully but it can't be overridden in child classes
System.out.println("========= exp1:: from methodSta2() ======");
}
default void method2() { System.out.println("--- exp1:: from method2() ---");}
//synchronized default void method3() { System.out.println("---");} // <-- Illegal modifier for the interface method method3; only public, abstract, default, static
// and strictfp are permitted
//final default void method3() { System.out.println("---");} // <-- error
}