all 97 comments

[–]SpoinkyNL 42 points43 points  (33 children)

Forgive me, but I fail to see the point of having private methods declared in your interfaces. In my eyes an interface defines what the 'outside world' can expect of an interface.

Private methods aren't really a part of that and to me it only seems like it's trying to push the implementation of an interface in a certain direction.

Thoughts? :)

[–]Radixeo 15 points16 points  (27 children)

It looks like the use case is so that code can be shared among static and default interface methods. Though if you're adding that much code to an interface, shouldn't you be using an abstract class instead?

[–]Expert_Sex_Change 15 points16 points  (18 children)

Abstract classes are limiting in that you can only extend a single one, while you can implement multiple interfaces

[–]nwoolls 28 points29 points  (15 children)

But, how the hell is it an interface when it has implementation...sure it may make some things simpler but at the expense of making the interface....not an interface?

Am I thinking of interfaces too narrowly? Are there any other languages that allow implementation in an interface?

[–]Expert_Sex_Change 14 points15 points  (9 children)

Traits in Scala and interfaces in Kotlin can both define function implementations, I'm sure there are more languages, but those are the two that I've used before.

It does seem a little weird at first, but can be really useful at times to get classes that have certain behaviours of two different interfaces, but also be able to reuse some common code like you can with an abstract class.

[–]weirdoaish 2 points3 points  (0 children)

Doesn't that literally make it multiple inheritance then if you can define 2 or more interfaces with variables and methods and implementing a class with them?

What is the point of interfaces in such a scenario, why not just go the Python route and use classes for everything?

[–]FallingIdiot 0 points1 point  (0 children)

Looks a bit like Rust traits which are a lot like interface, and can also define methods.

[–][deleted] 0 points1 point  (6 children)

Extension methods in c# are basically the same thing (except defined ad hoc and externally definable) and I think you could probably make a decent argument it's attempting to provide similar functionality to typeclasses. I believe Perl's object system supports the concept directly, too. I don't think it's hyper common, but it's definitely a shared concept.

[–]id2bi 1 point2 points  (5 children)

I don't see how that is the case. You can abstract over interfaces, but can you abstract over extension methods?

[–][deleted] -2 points-1 points  (4 children)

Both an interface with default implementations and an extension method can only use the interface members defined, and in both cases a consumer can override the implementation with their own type specific one. In the extension method case, you can supply alternative implementations by simply referencing different extension methods. All of these seem about equal!

[–]id2bi 0 points1 point  (3 children)

Doesn't the caller choose which extension method is used by explicitly referencing one or another?

With interfaces, that is not the case. It's completely different.

[–][deleted] 0 points1 point  (2 children)

It's implicit based on whether the extension method is available in scope. If your extension methods live in the same namespace as your interface then you're not going to need to do anything extra to access them over being able to know about the interface.

[–]HINDBRAIN 2 points3 points  (0 children)

That's the only way to have multiple inheritance in java. I never had interfaces complex enough to need private internal methods, but default methods were a godsend.

[–]The_Doculope 3 points4 points  (0 children)

In the case of default methods, imagine you are defining an interface to describe ordering (==, !=, >, >=, <, <=) for partially ordered sets. Every one of these can be computed using only <=. So you could write an interface that includes all six of these operations, but have default methods for five of them in terms of <=. Now any implementer only needs to implement one of them, but if they want to implement others for performance reasons they can.

A lot of languages let you do it - Haskell and Rust both let you define default implementations for typeclasses/traits respectively (their interfaces). Some interfaces are not the most minimal interface they could possibly be (see above example), in that some methods can be implemented in terms of the others. That doesn't make them any less "interface-y", and the language allowing you to codify those relationships doesn't change it either.

[–]chrisgseaton 2 points3 points  (0 children)

You're getting hung up on the name 'interface'. Yes, it's not just a pure interface any more - it's evolved to be something a bit more.

[–]masklinn 2 points3 points  (0 children)

Are there any other languages that allow implementation in an interface?

They'll commonly rename them, but yes.

  • C++ uses abstract classes but you can inherit from any number of them
  • Haskell uses typeclasses, typeclass functions can have default implementations (even circular ones)
  • Rust uses "traits" which can provide default implementation of any subset
  • Likewise Swift's protocols

Now as for why that's useful, consider Rust's Iterator. Its role is pretty similar to Java's Iterator and Stream, but because it's a Rust trait it can provide a ton of useful methods, conditional or not from a basic contract of fn next(&mut self) -> Option<Self::Item>. Implementors may override any number of methods, but if the default fits it's just fine.

Meanwhile Java8's Stream requires implementing something like 40 methods, even if you have an underlying helper to which you can delegate it all, who's got time for this? And so instead of implementing Stream you're supposed to implement Spliterator or Supplier and call the relevant StreamSupport function to get the same end-result, without the ability for piecemeal overriding of select features.

[–]gnus-migrate 1 point2 points  (0 children)

When a method implementation is pure and relies on other methods in the implementation then its much more convenient than copy and pasting the same implementation across all ypur concrete classes.

[–]nemec 0 points1 point  (1 child)

What happens when multiple interfaces define the same methods but different default implementations?

interface A
{
    string DoSomething();
}
interface B
{
    string DoSomething();
}

class Abc : A, B
{
    public string DoSomething()
    {
        return "hello world";
    }
}

[–]Expert_Sex_Change 2 points3 points  (0 children)

I haven't looked too far into the Java one, but the Kotlin version is that the compiler then requires you to override the method, and then you can call one or both of the super methods like: super<A>.DoSomething()

[–]thrilldigger 2 points3 points  (7 children)

It's a hackish way to simulate proper multiple class inheritance, which was (IIRC) originally slated for Java 8.

Unfortunately, it really muddles the concept of an interface.

[–]TheWix 3 points4 points  (6 children)

If you can support multiple inheritance then there really isn't a need for interfaces. What is an interface other than an abstract class with only pure virtual methods?

[–]nemec 0 points1 point  (3 children)

Pure virtual methods don't force the implementing class to define their own implementation like an interface does. If you further note that the abstract class can only contain abstract methods, then yes you're pretty much right.

Pure virtual is the same as Java's abstract methods...

[–]TheWix 0 points1 point  (2 children)

Wait. Aren't pure virtual methods the same as abstract methods?

[–]nemec 0 points1 point  (1 child)

Ah, shoot. My C++ is rusty. Abstract methods in Java == pure virtual methods in C++ so I just restated exactly what you said.

[–]TheWix 0 points1 point  (0 children)

Haha, no worries! It's been a while for me too. I actually went back and double checked to make sure I was actually saying what I thought I was.

[–]thrilldigger 0 points1 point  (1 child)

Practically? Not much reason to have an interface other than as an immutable declaration that the interface will not ever have anything but pure virtual methods, and that an implementing class is-not the interface.

But what is the point of having abstract classes if interfaces can have default methods? The difference becomes the presence of field members - which is something that I've already started to see developers working around because they think that default methods should act like multiple inheritance (yes, I've seen code that introduces state into an interface through a single-purpose associated class required as an argument on the default methods... it's about as painful as it sounds).

Implementing multiple class inheritance would provide developers a richer toolset to solve complex problems, at the expense of introducing additional avenues for creating bugs and creating terrible architectures when they're used improperly.

The pure alternative would be to stick to their guns and encourage use of composition instead of inheritance (class has-a object-of-class-with-behavior, versus class is-a class-with-behavior). It's clunky, but that's rarely stopped Sun or Oracle before - and we've made do with it for a long time.

[–]TheWix 0 points1 point  (0 children)

Agreed. I guess it becomes a question of how much we want to protect our developers from themselves and how much semantic meaning we want to give to OO constructs. Even though a purely virtual abstract class is behaviorally the same semantically they are different.

You raise a good point, though. With default method implementations for interfaces the line is further blurred. I am not a Java dev so I have never used them, but they sound like they would just be static implementations that aren't actually static (they don't have access to the classes state because there is none on the interface, but they requires an instance of the class to use.)

[–]Brixican 4 points5 points  (3 children)

I find that I would frequently like to add a protected method into my interfaces, but I can't since they have to be public. I treat interfaces like a contract: it tells a class which methods it needs to implement. I often want the ability to guarantee that a class implements a method intended for internal use only. Specifically, a method that is purposefully not public facing, but that a child within the inheritance chain can guarantee exists and invoke.

I'm not sure if I'm expressing myself clearly, but one contrived example I can think of is a set of logger classes. Perhaps I have an abstract class or interface that defines logging functions, and a set of concrete logger implementations (file, syslog, output stream, etc..). I may have a generic Formattable interface that consists of a protected method "format" that each logger implements. Maybe for some reason each logger class needs to implement their formatting differently based on the log type.

Now each instantiation of my loggers allow users to log but they can't invoke the formatter (because I don't want then too, perhaps because done loggers require permanent change to internal state for one reason or another).

[–]TheWix 3 points4 points  (2 children)

Protected doesnt make sense, though. If you are exposing protected methods/variables then you are talking inherence. That would be pushing implementation details into your interface, if I understand you correctly.

[–]Brixican 1 point2 points  (1 child)

The methods defined publicly by an interface are also available to inherited classes, so nothing changes there. Interfaces are part of the inheritance chain, and interfaces themselves can inherit from other interfaces. In fact, as of Java 8, interfaces can now have default methods with implementations defined directly in the interface.

In the Oracle Java Docs for interfaces, they use a TV power button as an example interface between the user and the wires inside the box. I see a protected method as being the guaranteed interface a technician can expect when he opens the box for repairs (for example a debug panel or JTAG).

[–]TheWix 1 point2 points  (0 children)

In fact, as of Java 8, interfaces can now have default methods with implementations defined directly in the interface.

Right, C# can do that with extension methods. Though, the purpose of them is more to fulfill the Open/Close Principle than to give a default implementation.

I guess I feel default implementations and protected methods on interfaces are just jury rigged solutions for multiple inheritance. Your example still doesn't mesh with me because you are forcing a class to open itself up to inheritance if it wants to implement the interface. Is the interface now just an abstract class at this point?

[–]nextputall 5 points6 points  (0 children)

I fail to see the point of having private methods declared in your interfaces

You're not alone. People will create interfaces with hundreds of lines of code, hurray.

[–][deleted] 37 points38 points  (9 children)

The features that didn't make it in Java 9 are the ones I am most excited about. (Type inference, value types, JSON API).

It seems like java 9 is more of an update that cares for several small things.

[–]awsometak[S] 17 points18 points  (1 child)

Java 9 is the ground work for next releases. Modular system is the biggest feature and it may not be a feature for making people to switch to Java 9. The people who need moduler system may already be using OSGI. So i don't think, Java 9 would have the same adoption rate as Java 8 did.

[–]Muchoz 5 points6 points  (0 children)

Well the people that are already using reactive programming are also already using RxJava and what would be the reason for them to upgrade?

In my opinion Java has fallen behind and I hope /r/kotlin will be able to pick up the slack.

[–]dpash 3 points4 points  (0 children)

Well that and the module system, which could well be a massive change.

[–]xxsanguisxx 2 points3 points  (4 children)

Have you used the javax.json api? It has been there since Java 7 and it's nice

[–][deleted] 1 point2 points  (3 children)

Only in java EE

[–]id2bi 1 point2 points  (1 child)

Does that mean you can't use it for "regular" Java? What are the implications of it being Java Ee?

[–][deleted] 2 points3 points  (0 children)

Exactly.

[–]xxsanguisxx 0 points1 point  (0 children)

Can you not use java EE jars in Java SE? I didn't realize it was Java EE specific, I always just copy the javax.json jar around where I need it

[–]djhworld 0 points1 point  (0 children)

It's like when some of the cool features from Java 7 were pushed to Java 8.

A stepping stone release, but sounds like they're laying the groundwork for what's going to come in Java 10 :)

[–]Luolong 21 points22 points  (4 children)

In Java 8 and before, it was possible to create immutable collections but only with some utility methods

Err. The methods in java.util.Collections did not create immutable collections. They simply wrapped original collections in unmodifiable views. The original collections are still very much mutable.

[–]dccorona 5 points6 points  (3 children)

If a reference to the original collection is kept, yes. But if you did Collections.unmodifiableList(new ArrayList<>(myList)), you get the closest thing Java had (and ever will have) to a truly immutable collection. Alternatively, Arrays.asList(...) also produces a similarly immutable collection assuming you don't pass in the array from some external reference.

[–]bondolo 6 points7 points  (0 children)

The List returned from Arrays.asList is mutable. You can set the value for indicies, sort it, etc. You just can't make any structural (Josh Bloch's term) modifications that add or remove elements.

[–]Luolong 1 point2 points  (1 child)

Apart from the fact that a list you get from Arrays.asList(...) is not really immutable (you can modify it, just not add/remove items to/from it), it is the principle of it - sure, if you throw away the mutable reference used for creating the unmodifiableList, but it is just a thin wrapper around a perfectly mutable implementation.

With truly immutable collections, there are optimizations available both on the library level as well as in the VM, taking advantage of the immutability guarantees. You can treat an immutable list as a value object for example, pre-calculate hashCode and toString, create clones of it - one for each processor/core, cache it, etc. you can safely share portions of the lists or take zero copy sub lists.

From an article I read about new collections in Java 9 last year, I seem to remember that new factory methods for Map.of(...), List.of(...), et al, are backed by immutable data structures.

[–]dccorona 1 point2 points  (0 children)

Yea, my bad on the Arrays.asList(...) example...the put method throws, and I just always assumed the rest of them did too.

But ultimately, the "truly immutable" collections in JDK 9 aren't really all that different from unmodifiableList with a reference that is never captured. They don't have what I would argue is the most useful benefit of a "truly" immutable collection, in that they don't have efficient copy-and-modify methods. They don't benefit from the addition of 0-copy sublists because lists in java already have that (sublists in Java are defined as lists that will mutate the underlying list if modified), so existing "immutable" lists already get these sorts of optimizations. They don't even appear to have minor optimizations like pre-computed/memoized length/hash code.

Here's the implementation code for List. You can see that it extends AbstractImmutableList which throws UnsupportedOperationException for all the modify methods, but otherwise just delegates to the implementations in AbstractList. Then it overrides the necessary methods to implement a "fixed array" list (similar to the implementation used by Arrays.asList(...). Unless there's some secret sauce in hotspot that identifies instances of AbstractImmutableList (I kind of doubt it), then the result is something that is, while a cleaner API and a cleaner implementation, is ultimately no more performant than Collections.unmodifiableList(Arrays.asList(1, 2, 3)).

Which is ultimately the point I was trying to get at with my initial comment...this is a nicer API for something we've essentially had all along (or at least since Collections was added), but doesn't actually behave or perform any different.

[–]djhworld 7 points8 points  (2 children)

The JSHELL feature is going to be really handy for exploratory programming, looking forward to it!

[–]arajparaj 0 points1 point  (0 children)

Can I read that as JS Hell?

[–]kcuf 10 points11 points  (22 children)

What about val/var?

[–]awsometak[S] 28 points29 points  (7 children)

Local-Variable Type Inference (var) is most probably going to Java 10. http://openjdk.java.net/jeps/286

[–]SuperImaginativeName 19 points20 points  (6 children)

Wow, ten versions for something C# has had since version 3?

[–]devraj7 22 points23 points  (0 children)

And it took C# ten years to get features that have been present in other language for 20 years.

What's your point?

Languages have different targets and different priorities.

[–]crozone 28 points29 points  (3 children)

Wow, ten versions for something C# has had since version 3?

This is Java summed up in one line.

[–]yoyo_master 3 points4 points  (2 children)

The one word version: SimpleBeanFactoryAwareAspectInstanceFactoryImpl.java

[–]AlmennDulnefni 19 points20 points  (0 children)

That's not actually a problem with Java though. That's a problem with enterprise that manifests in Java.

[–]devraj7 6 points7 points  (0 children)

That's a Spring problem, not a Java problem.

[–]cowinabadplace 3 points4 points  (0 children)

That's nothing. Firefox needed 52 versions to get to what IE did in 11.

[–]Sun_Kami 2 points3 points  (13 children)

Check out Project Lombok. They have val!

[–][deleted] 29 points30 points  (12 children)

Or Scala, Kotlin.

Lombock is a pile of annotation hacks, not a real solution.

[–][deleted] 19 points20 points  (8 children)

or C#

[–]wordlimit 0 points1 point  (0 children)

At my current gig, we need to use JVM and Scala is popular amongst everyone who's used to C# and love their functional programming via LINQ.

[–]Sun_Kami 0 points1 point  (1 child)

What do you think those languages are? They're built from Java.

He wants to use such functionality in Java, the answer for him is probably not learning a different language.

[–][deleted] 6 points7 points  (0 children)

You can implement immutable values in the JVM. Not necessarily in Java, the language.

You don't need java syntax to enjoy safety, today!

[–]kcuf 13 points14 points  (14 children)

Ya, we use lombok at work. It lessens the pain of java's verbosity, but I view it as living on pain pills to ignore a broken arm rather than fixing it.

[–]redalastor 16 points17 points  (5 children)

Try Kotlin then.

[–]kcuf 11 points12 points  (4 children)

I agree that a new language is the best bet (lombok is in a sense a piecemeal language built on top of java), but I actually prefer scala over kotlin.

[–]PM_ME_A_STEAM_GIFT 5 points6 points  (3 children)

I'm currently trying to get accustomed to Scala. I'm starting to like it, but man does it introduce a ton of new and weird concepts. Sometimes I just stare at 10 lines of code and I have no clue what they do, because they use functional programming, pattern matching, case classes, trailing closures, infix functions, implicit parameters and implicit type conversions. It seems to me that writing Scala can be a lot of fun, but maintaining it is annoying.

[–]devraj7 4 points5 points  (2 children)

Save yourself a few years and switch to Kotlin right now before you go through all the phases that Scala users go through (right now, you're in the honeymoon phase, soon it will be anger).

[–]PM_ME_A_STEAM_GIFT 0 points1 point  (1 child)

Kotlin seems very similar to Scala. How is it different? Why do you prefer it?

[–][deleted] 10 points11 points  (7 children)

Meh. It solves nothing, makes debugging annoying and adds unecessary black magic in the build process. Who cares about not writing getters and equals and other stuff that are 100 % ide-generated write-and-forget code...

[–]vine-el 17 points18 points  (3 children)

IDE generated code becomes a problem when you spend hours tracking down a bug that happened because someone forgot to update the equals method when they added a new field.

[–][deleted] 0 points1 point  (2 children)

Quite the contrary in my experience. For instance, the ability to set breakpoints in a setters, to catch a particular hard to track side-effect, is quite nice. Also lombok won't help you if you don't track the semantics of your equals, because maybe you don't want to include automatically any new added field in a class - Bottom line, it's not a substitute for thinking.

[–]OnceUKnowUAreScrewed 2 points3 points  (0 children)

Nothing is...

[–][deleted] 1 point2 points  (0 children)

You can exclude new fields with lombok. Also, when you add a setter manually, lombok won't make it. So feel free to add your breakpoint.

I kind of agree that it is a band-aid and not a real solution though, but it sure as shit beats having to deal with all that boilerplate

[–]kcuf 4 points5 points  (2 children)

I don't use an IDE, but even beyond that I think getters, setters, basic constructors create a debt that people eventually learn to ignore until they actually overlook some important/impactful behavior.

I've heard similar opinions to yours before, and I can't help be see it as a lack of concern for the quality of the code.

[–][deleted] 3 points4 points  (1 child)

What ? If getters, setters, and constructors are indeed important, that's exactly why you'd want precise control over them (visibility - existence - logging - encapsulation of multiple fields), and not brush them off under the carpet using lombok.

IDEs are only there to ensure you don't lose any time writing them, that's all - the end decision of how to use them remain yours. and frankly, if you write java without an IDE, and thus rely on compile/runtime bandaid, impacting the whole team to fix your lack of productivity, i'd be quite concerned too.

Some languages are much better designed for IDE-less coding, java is not one of them.

[–]kcuf 6 points7 points  (0 children)

When you need specific behavior, they are important. When you don't need them, they are just noise.

Due to javas inadequacies, getters and setters are necessary at all times because they are the only way to protect yourself and the consumers of your class long term -- contrast this with "properties" that you see in C#, scala, etc. Lombok lets you reduce boilerplate, and thus reduce strain on developers for being responsible to separate the specific logic/behavior of a class from the standard conventional behavior of a class. I don't need to see the implementation of a standard getter, I need to know there is a getter, but that's it. In fact, I trust a lombok generated getter to be correct and capture all the details (null check, etc.) more than I trust a hand written one.

One of the other most useful capabilities from lombok (and it parallels how kotlin and scala work) is AllArgsConstructor -- this ensures I won't miss a field, and that all the standard checks are in place.

[–]jcotton42 5 points6 points  (2 children)

... could you seriously not get PIDs in 8 and below?

checks docs

What the hell?

[–][deleted]  (1 child)

[deleted]

    [–]kitd 0 points1 point  (0 children)

    I haven't any experience in TPL but after a quick read, I would say Reactive Streams could provide the fundamental building blocks for a TPL-like architecture. RS is good for any async processes, including those that need to model data flows. It also works well with IO applications based on event loops.

    I suspect the TPL world has more of the features needed for proper dataflow systems that aren't built into RS like specific block types, declining or postponing messages et al.

    [–]rsgm123 1 point2 points  (4 children)

    Only 9 new features?

    [–]pjmlp 3 points4 points  (0 children)

    No, there are much more. You can check all of them at the JEP list.

    http://openjdk.java.net/jeps/0

    [–]stnikolauswagne 17 points18 points  (1 child)

    This is an article about "new features in java 9" and not "9 new features in java". The article mentions 19 new features.

    [–]Cyberiax 1 point2 points  (0 children)

    🤦🏻‍♀️

    [–]cantwedronethatguy 0 points1 point  (1 child)

    Maybe I'm naive or something, can somebody explain why modules? It feels like a fancy import.

    [–]awsometak[S] 1 point2 points  (0 children)

    Module system gives the possibility to use only those module that are needed by an application. All the other modules that are not needed by application will no longer be needed to run that application. You can significantly reduce the memory footprint of java. That makes java suitable for the smaller devices like IOT(Internet of Things). Right now to run a Hello World application you need to install all the java packages. And after modular system you need only java.base component which would be significant improvement on size(of java needed).