What's the differences between Go and Java about interface? [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Recently I've been asked a question which is, what's the difference between Golang and Java about interface?
I know there are some 'syntactic sugar level' differences, what I am interested is anything beneath the ground, like how does Golang and Java implement interface? What's the most difference? Which one is more efficient? Why?
Could anyone post blogs link or source code about this topic? Source code is better.

Go Data Structures: Interfaces by Russ Cox
Go's interfaces—static, checked at compile time, dynamic when asked
for
Go's interfaces let you use duck typing like you would in a purely
dynamic language like Python but still have the compiler catch obvious
mistakes like passing an int where an object with a Read method was
expected, or like calling the Read method with the wrong number of
arguments.
Interfaces aren't restricted to static checking, though. You can check
dynamically whether a particular interface value has an additional
method.
Interface Values
Languages with methods typically fall into one of two camps: prepare
tables for all the method calls statically (as in C++ and Java), or do
a method lookup at each call (as in Smalltalk and its many imitators,
JavaScript and Python included) and add fancy caching to make that
call efficient. Go sits halfway between the two: it has method tables
but computes them at run time. I don't know whether Go is the first
language to use this technique, but it's certainly not a common one.
Interface values are represented as a two-word pair giving a pointer
to information about the type stored in the interface and a pointer to
the associated data. Assigning b to an interface value of type
Stringer sets both words of the interface value.
The first word in the interface value points at what I call an
interface table or itable (pronounced i-table; in the runtime
sources). The itable begins with some metadata about the types
involved and then becomes a list of function pointers. Note that the
itable corresponds to the interface type, not the dynamic type.
The second word in the interface value points at the actual data, in
this case a copy of b.
Go's dynamic type conversions mean that it isn't reasonable for the
compiler or linker to precompute all possible itables: there are too
many (interface type, concrete type) pairs, and most won't be needed.
Instead, the compiler generates a type description structure for each
concrete type like Binary or int or func(map[int]string). Among other
metadata, the type description structure contains a list of the
methods implemented by that type. Similarly, the compiler generates a
(different) type description structure for each interface type like
Stringer; it too contains a method list. The interface runtime
computes the itable by looking for each method listed in the interface
type's method table in the concrete type's method table. The runtime
caches the itable after generating it, so that this correspondence
need only be computed once.
Method Lookup Performance
Smalltalk and the many dynamic systems that have followed it perform a
method lookup every time a method gets called. For speed, many
implementations use a simple one-entry cache at each call site, often
in the instruction stream itself. In a multithreaded program, these
caches must be managed carefully, since multiple threads could be at
the same call site simultaneously. Even once the races have been
avoided, the caches would end up being a source of memory contention.
Because Go has the hint of static typing to go along with the dynamic
method lookups, it can move the lookups back from the call sites to
the point when the value is stored in the interface.
How does Go interface dispatch work?
Method dispatch on an interface variable is the same as a vtable
dispatch.
The first time a concrete type hits an interface type, it builds a
hash table entry that points to a vtable. Second and subsequent
assignments of the same type will do a much cheaper hash lookup to
find the vtable. But the method dispatch itself is always
equivalent to a vtable lookup.
Spec: Interface types
For more details see: Go: What's the meaning of interface{}?
Here, two interesting use cases of interfaces in Go:
Why are interfaces needed in Golang?
The error type is an interface type: How to compare Golang error objects
Calculate Area of 4 different shapes: Circle, Square, Rectangle and Triangle:
Explain Type Assertions in Go
Here in Go you don't need do any thing special like Java keyword implements for implementing an interface, in Go it is enough that your type just has that method with right signature.
Here is the code (try it on The Go Playground):
package main
import "fmt"
type Work struct {
Name string
}
func (t Work) String() string {
return "Stringer called."
}
func main() {
w := Work{"Hi"}
fmt.Println(w)
}
output:
Stringer called.
Spec: type Stringer, and see the source:
type Stringer interface {
String() string
}
Stringer is implemented by any value that has a String method, which
defines the “native” format for that value. The String method is used
to print values passed as an operand to any format that accepts a
string or to an unformatted printer such as Print.
Also see:
Why can't I assign a *Struct to an *Interface?
Meaning of a struct with embedded anonymous interface?
Embedded Interface
Golang: what's the point of interfaces when you have multiple inheritence

Related

Why generics were not used in get method in Java HashMap implementation [duplicate]

What are the reasons behind the decision to not have a fully generic get method
in the interface of java.util.Map<K, V>.
To clarify the question, the signature of the method is
V get(Object key)
instead of
V get(K key)
and I'm wondering why (same thing for remove, containsKey, containsValue).
As mentioned by others, the reason why get(), etc. is not generic because the key of the entry you are retrieving does not have to be the same type as the object that you pass in to get(); the specification of the method only requires that they be equal. This follows from how the equals() method takes in an Object as parameter, not just the same type as the object.
Although it may be commonly true that many classes have equals() defined so that its objects can only be equal to objects of its own class, there are many places in Java where this is not the case. For example, the specification for List.equals() says that two List objects are equal if they are both Lists and have the same contents, even if they are different implementations of List. So coming back to the example in this question, according to the specification of the method is possible to have a Map<ArrayList, Something> and for me to call get() with a LinkedList as argument, and it should retrieve the key which is a list with the same contents. This would not be possible if get() were generic and restricted its argument type.
An awesome Java coder at Google, Kevin Bourrillion, wrote about exactly this issue in a blog post a while ago (admittedly in the context of Set instead of Map). The most relevant sentence:
Uniformly, methods of the Java
Collections Framework (and the Google
Collections Library too) never
restrict the types of their parameters
except when it's necessary to prevent
the collection from getting broken.
I'm not entirely sure I agree with it as a principle - .NET seems to be fine requiring the right key type, for example - but it's worth following the reasoning in the blog post. (Having mentioned .NET, it's worth explaining that part of the reason why it's not a problem in .NET is that there's the bigger problem in .NET of more limited variance...)
The contract is expressed thus:
More formally, if this map contains a
mapping from a key k to a value v such
that (key==null ? k==null :
key.equals(k)), then this method
returns v; otherwise it returns null.
(There can be at most one such
mapping.)
(my emphasis)
and as such, a successful key lookup depends on the input key's implementation of the equality method. That is not necessarily dependent on the class of k.
It's an application of Postel's Law, "be conservative in what you do, be liberal in what you accept from others."
Equality checks can be performed regardless of type; the equals method is defined on the Object class and accepts any Object as a parameter. So, it makes sense for key equivalence, and operations based on key equivalence, to accept any Object type.
When a map returns key values, it conserves as much type information as it can, by using the type parameter.
I think this section of Generics Tutorial explains the situation (my emphasis):
"You need to make certain that the generic API is not unduly restrictive; it must
continue to support the original contract of the API. Consider again some examples
from java.util.Collection. The pre-generic API looks like:
interface Collection {
public boolean containsAll(Collection c);
...
}
A naive attempt to generify it is:
interface Collection<E> {
public boolean containsAll(Collection<E> c);
...
}
While this is certainly type safe, it doesn’t live up to the API’s original contract.
The containsAll() method works with any kind of incoming collection. It will only
succeed if the incoming collection really contains only instances of E, but:
The static type of the incoming
collection might differ, perhaps
because the caller doesn’t know the
precise type of the collection being
passed in, or perhaps because it is a
Collection<S>,where S is a
subtype of E.
It’s perfectly
legitimate to call containsAll() with
a collection of a different type. The
routine should work, returning false."
Compatibility.
Before generics were available, there was just get(Object o).
Had they changed this method to get(<K> o) it would have potentially forced massive code maintenance onto java users just to make working code compile again.
They could have introduced an additional method, say get_checked(<K> o) and deprecate the old get() method so there was a gentler transition path. But for some reason, this was not done. (The situation we are in now is that you need to install tools like findBugs to check for type compatibility between the get() argument and the declared key type <K> of the map.)
The arguments relating to the semantics of .equals() are bogus, I think. (Technically they're correct, but I still think they're bogus. No designer in his right mind is ever going to make o1.equals(o2) true if o1 and o2 do not have any common superclass.)
The reason is that containment is determined by equals and hashCode which are methods on Object and both take an Object parameter. This was an early design flaw in Java's standard libraries. Coupled with limitations in Java's type system, it forces anything that relies on equals and hashCode to take Object.
The only way to have type-safe hash tables and equality in Java is to eschew Object.equals and Object.hashCode and use a generic substitute. Functional Java comes with type classes for just this purpose: Hash<A> and Equal<A>. A wrapper for HashMap<K, V> is provided that takes Hash<K> and Equal<K> in its constructor. This class's get and contains methods therefore take a generic argument of type K.
Example:
HashMap<String, Integer> h =
new HashMap<String, Integer>(Equal.stringEqual, Hash.stringHash);
h.add("one", 1);
h.get("one"); // All good
h.get(Integer.valueOf(1)); // Compiler error
There is one more weighty reason, it can not be done technically, because it brokes Map.
Java has polymorphic generic construction like <? extends SomeClass>. Marked such reference can point to type signed with <AnySubclassOfSomeClass>. But polymorphic generic makes that reference readonly. The compiler allows you to use generic types only as returning type of method (like simple getters), but blocks using of methods where generic type is argument (like ordinary setters).
It means if you write Map<? extends KeyType, ValueType>, the compiler does not allow you to call method get(<? extends KeyType>), and the map will be useless. The only solution is to make this method not generic: get(Object).
Backwards compatibility, I guess. Map (or HashMap) still needs to support get(Object).
I was looking at this and thinking why they did it this way. I don't think any of the existing answers explains why they couldn't just make the new generic interface accept only the proper type for the key. The actual reason is that even though they introduced generics they did NOT create a new interface. The Map interface is the same old non-generic Map it just serves as both generic and non-generic version. This way if you have a method that accepts non-generic Map you can pass it a Map<String, Customer> and it would still work. At the same time the contract for get accepts Object so the new interface should support this contract too.
In my opinion they should have added a new interface and implemented both on existing collection but they decided in favor of compatible interfaces even if it means worse design for the get method. Note that the collections themselves would be compatible with existing methods only the interfaces wouldn't.
We are doing big refactoring just now and we were missing this strongly typed get() to check that we did not missed some get() with old type.
But I found workaround/ugly trick for compilation time check: create Map interface with strongly typed get, containsKey, remove... and put it to java.util package of your project.
You will get compilation errors just for calling get(), ... with wrong types, everything others seems ok for compiler (at least inside eclipse kepler).
Do not forget to delete this interface after check of your build as this is not what you want in runtime.

Java Enum<T> vs T as variable type

Is there any difference between this declaration
Thread.State state = Thread.State.NEW;
and that
Enum<Thread.State> state = Thread.State.NEW;
in Java? Instead of the second option is a bit longer?
It's the same case as comparing between:
Child o = someChild;
and
Parent o = someChild;
Enum is the parent class of all enum types. Therefore, with the second line, the code cannot contain references to specific members of Thread.State, specifically the members described in this section of the language spec.
Is there any difference ....
In practice, in this particular case, probably no.
In theory, Thread.State is a subtype of Enum<Thread.State>. If Thread.State declared (non-private) fields or methods, then you could use them via the first declaration of state, but not the second one.
In general, the first form is preferable ... for that reason.
Also, I don't think you would be able to see an enum's static methods values() and valueOf via the variable declared in the second declaration; e.g.
state.valueOf("BLOCKED")
However, calling a static method via an instance reference is bad style.
Two practical differences (as opposed to language-lawyerly reasons) that come to mind:
If you declare state as an Enum<Thread.State>, then you won't be able to pass it to any methods that expect a Thread.State.
If you declare state as an Enum<Thread.State>, you'll leave the reader — whoever needs to touch this code in the future — wondering why you've written it that way.
Neither of these is a terribly deep reason; we could easily imagine a parallel universe where most people used Enum<Thread.State> instead of Thread.State, just as (in our universe) most people use List<...> instead of ArrayList<...> (when possible). But since most people don't do that in our universe, you're better off just following the common pattern, to minimize the risk of confusion and accidental incompatibility.
Incidentally, in case this is going to be your next question . . . the main situation where you would use Enum is when you want to write something generic that works for many different enum types. An example of this in the JDK is EnumMap<K extends Enum<K>,V>, which is a special map implementation that gets space and performance benefits out of knowing that its keys are enum values.
(And note, incidentally, that you can't write EnumMap<Enum<Thread.State>, String>, because Enum<Thread.State> doesn't extend Enum<Enum<Thread.State>>. Instead, you must write EnumMap<Thread.State, String>. So this is an example of difference #1 that I mentioned above: if you declare state as an Enum<Thread.State>, then you can't use it as a key in an enum-map.)

Why does StructuredArray need to be non-constructible?

This talk at 34:00 describes the design of StructuredArrays for Java. Everything's rather clear, except for on thing:
It shouldn't be constructible, i.e., the instance may be only obtainable by some static factory method like newInstance. At the same time, they should be subclassible, which means that there must be a public constructor and the non-constructibility will be assured at runtime. This sounds very hacky, so I wonder why?
I'm aware about the advantages of factories in general and static factory methods in particular. But what do we get here, so that it makes the hack acceptable?
The point of the StructuredArray class is that someday it can be replaced with an intrinsic implementation that allocates the whole array, including the component objects, as one long block of memory. When this happens, the size of the object will depend on the number of elements and the element class.
If StructuredArray had a public constructor, then you could write x = new StructuredArray<>(StructuredArray.class, MyElement.class, length). This doesn't seem to present any problem, except that in bytecode, this turns into a new instruction that allocates the object, and then a separate invokespecial instruction to call the object's constructor.
You see the problem -- the new instruction has to allocate the object, but it cannot, because the size of the object depends on constructor parameters (the element class and length) that it doesn't have! Those aren't passed until the constructor call that follows sometime later.
There are ways to around problems like this, but they're all kinda gross. It makes a lot more sense to encapsulate construction in a static factory method, because then you just can't write new StructuredArray..., and the JVM doesn't have to use any "magic" to figure out how much memory to allocate in the new instruction for StructuredArray, because there just can't be any such instructions*.
If some later JVM wants to provide an intrinsic implementation of the static factory that allocates a contiguous array, then it's no problem -- it gets all the information it needs in the factory method invocation.
NB* - yes, OK, technically you can write new StructuredArray..., but it doesn't make a useful object for you.
Semantics Going through the API documentation my understanding is that it is a question mostly of Semantics. And providing a Fluent API. Also if you go to the conclusion slide of the presentation you should notice that the Semantics bullet comes first (if we don't count the source code url).
If we pick the normal Arrays. They present a clear semantics of:
Type of the array
length of the array
type of the elements
As a result
We have a unified model of working with arrays. And the API is crystal clear. There are no 10 different ways of working with arrays. I believe that for the Java language developers, this cleanness of the api is of extreme importance. Forcing the non-contructability they are implicitly forcing us to use the API the way they want us to use it.
Construction
Since the StructuredArray essentially is array as well. Presenting a constructor will immediately force us to use the Concrete implementation of the StructuredArray which automatically will create problems introducing this unified model of "What exactly is an "Array?".
This is why going through the Javadoc we can see the way the StructuredArray is actually contructed:
static <S extends StructuredArray<T>,T> S newInstance(java.lang.invoke.MethodHandles.Lookup lookup,
java.lang.Class<S> arrayClass,
java.lang.Class<T> elementClass,
java.util.Collection<T> sourceCollection)
What is visible here is that the StructuredArray is forcing several things:
It is forcing all client classes to work with "StructuredArray" and not with the concrete implementation.
StructuredArray is essentially immutable.
The immutability means that there is a strict notation of Length.
Structured Array has a source of elements. Which once consumed may be disposed.
And similarly to the regular Array, the Structured array has a concept of TYPE of elements.
I believe that there is a very strong notation of semantics and also the authors are giving us an excellent hint in how exactly the coding is supposed to happen.
Another interesting feature of the structured arrays is the ability to pass a constructor. Again we are talking about a strong decoupling of the interface and the API from the actual implementation.
Array Model
My words are further confirmed by examining the StructuredArrayModel
http://objectlayout.github.io/ObjectLayout/JavaDoc/index.html?org/ObjectLayout/StructuredArray.html
StructuredArrayModel(java.lang.Class<S> arrayClass, java.lang.Class<T> elementClass, long length)
Three things are visible from the constructor:
- Array class
- Type of the elements
- length
Observing further the constructs that the Structured Array supports:
An array of structs:
struct foo[];
A struct with a struct inside:
struct foo { int a; bar b; int c; };
A struct with an array at the end:
struct foo { int len; char[] payload; };
It is fully supported by the StructuredArrayModel
In contrast to the StructuredArray we have the ability to instantiate easily concrete implementations of the model.
StructuredArray presents us the ability to pass pseudo constructors http://objectlayout.github.io/ObjectLayout/JavaDoc/org/ObjectLayout/CtorAndArgs.html
newInstance(CtorAndArgs<S> arrayCtorAndArgs, java.lang.Class<T> elementClass, long length)

java's typing system: prefer interface types to class types as method parameters/return values

I just making an effort to understand the power of the interfaces and how to use them to the best advantage.
So far, I understood that interfaces:
enable us to have another layer of abstraction, separate the what (defined by the interface) and the how (any valid implementation).
Given just one single implementation I would just build a house (in one particular way) and say here, its done instead of coming round with a building plan (the interface) and ask you, other developers to build it as i expect.
So far, so good.
What still puzzles me is why to favor interface types over class types when it comes to method parameters and return values. Why is that so? What are the benefits (drawbacks of the class approach)?
What interests me the most is how this actually translates into code.
Say we have a sort of pseudo mathInterface
public interface pseudoMathInterface {
double getValue();
double getSquareRoot();
List<Double> getFirstHundredPrimes();
}
//...
public class mathImp implements pseudoMathInterface { }
//.. actual implementation
So in the case of getPrimes() method I would bound it to List, meaning any concrete implementation of the List interface rather than a concerete implementation such as ArrayList!?
And in terms of the method parameter would I once again broaden my opportunities whilst ensuring that i can do with the type whatever i would like to do given it is part of the interface's contract which the type finally implements.!?
Say you are the creator of a Maven dependency, a JAR with a well-known, well-specified API.
If your method requests an ArrayList<Thing>, treating it is a collection of Things, but all I have got is a HashSet<Thing>, your method will twist my arm into copying everything into an ArrayList for no benefit;
if your method declares to return an ArrayList<Thing>, which (semantically) contains just a collection of Things and the index of an element within it carries no meaning, then you are forever binding yourself to returning an actual ArrayList, even though e.g. the future course of the project makes it obvious that a custom collection implementation, specifically tailored to the optimization of the typical use case of this method, is desperately needed to improve a key performance bottleneck.
You are forced to make an API breaking change, again for no benefit to your client, but just to fix an internal issue. In the meantime you've got people writing code which assumes an ArrayList, such as iterating through it by index (there is an extremely slight performance gain to do so, but there are early optimizers out there to whom that's plenty).
I propose you judiciously generalize from the above two statements into general principles which capture the "why" of your question.
An important reason to prefer interfaces for formal argument types is that it does not bind you to a particular class hierarchy. Java supports only single inheritance of implementation (class inheritance), but it supports unlimited inheritance of interface (implements).
Return types are a different question. A good rule of thumb is to prefer the most general possible argument types, and the most specific possible return types. The "most general possible" is pretty easy, and it clearly lines up with preferring interface types for formal arguments. The "most specific possible" return types is trickier, however, because it depends on just what you mean by "possible".
One reason for using interface types as your methods' declared return types is to allow you to return instances of non-public classes. Another is to preserve the flexibility to change what specific type you return without breaking dependent code. Yet another is to allow different implementations to return different types. That's just off the top of my head.
So in the case of getPrimes() method I would bound it to List, meaning any concrete implementation of the List interface rather than a concerete implementation such as ArrayList!?
Yes, this allows the method to later then change what List type it returns without breaking client code that uses the method.
Besides having the ability to change what object is really passed to/returned from a method without breaking code, sometimes it may be better to use an interface type as a parameter/return type to lower the visibility of fields and methods available. This would reduce overall complexity of the code that then uses that interface type object.

How are java interfaces implemented internally? (vtables?)

C++ has multiple inheritance. The implementation of multiple inheritance at the assembly level can be quite complicated, but there are good descriptions online on how this is normally done (vtables, pointer fixups, thunks, etc).
Java doesn't have multiple implementation inheritance, but it does have multiple interface inheritance, so I don't think a straight forward implementation with a single vtable per class can implement that. How does java implement interfaces internally?
I realize that contrary to C++, Java is Jit compiled, so different pieces of code might be optimized differently, and different JVMs might do things differently. So, is there some general strategy that many JVMs follow on this, or does anyone know the implementation in a specific JVM?
Also JVMs often devirtualize and inline method calls in which case there are no vtables or equivalent involved at all, so it might not make sense to ask about actual assembly sequences that implement virtual/interface method calls, but I assume that most JVMs still keep some kind of general representation of classes around to use if they haven't been able to devirtualize everything. Is this assumption wrong? Does this representation look in any way like a C++ vtable? If so do interfaces have separate vtables and how are these linked with class vtables? If so can object instances have multiple vtable pointers (to class/interface vtables) like object instances in C++ can? Do references of a class type and an interface type to the same object always have the same binary value or can these differ like in C++ where they require pointer fixups?
(for reference: this question asks something similar about the CLR, and there appears to be a good explanation in this msdn article though that may be outdated by now. I haven't been able to find anything similar for Java.)
Edit:
I mean 'implements' in the sense of "How does the GCC compiler implement integer addition / function calls / etc", not in the sense of "Java class ArrayList implements the List interface".
I am aware of how this works at the JVM bytecode level, what I want to know is what kind of code and datastructures are generated by the JVM after it is done loading the class files and compiling the bytecode.
The key feature of the HotSpot JVM is inline caching.
This doesn't actually mean that the target method is inlined, but means that an assumption
is put into the JIT code that every future call to the virtual or interface method will target
the very same implementation (i.e. that the call site is monomorphic). In this case, a
check is compiled into the machine code whether the assumption actually holds (i.e. whether
the type of the target object is the same as it was last time), and then transfer control
directly to the target method - with no virtual tables involved at all. If the assertion fails, an attempt may be made to convert this to a megamorphic call site (i.e. with multiple possible types); if this also fails (or if it is the first call), a regular long-winded lookup is performed, using vtables (for virtual methods) and itables (for interfaces).
Edit: The Hotspot Wiki has more details on the vtable and itable stubs. In the polymorphic case, it still puts an inline cache version into the call site. However, the code actually is a stub that performs a lookup in a vtable, or an itable. There is one vtable stub for each vtable offset (0, 1, 2, ...). Interface calls add a linear search over an array of itables before looking into the itable (if found) at the given offset.

Categories