If you are not sure if the website you would like to visit is secure, you can verify it here. Enter the website address of the page and see parts of its content and the thumbnail images on this site. None (if any) dangerous scripts on the referenced page will be executed. Additionally, if the selected site contains subpages, you can verify it (review) in batches containing 5 pages.
favicon.ico: nipafx.dev/java-default-methods-interface-evolution-failure - Interface Evolution With Defau.

site address: nipafx.dev/java-default-methods-interface-evolution-failure redirected to: nipafx.dev/java-default-methods-interface-evolution-failure

site title: Interface Evolution With Default Methods Part II: Interfaces // nipafx

Our opinion (on Tuesday 15 September 2026 4:55:42 UTC):

GREEN status (no comments) - no comments
After content analysis of this website we propose the following hashtags:


Hashtags existing on this website:



page from cache: 26 minutes ago
Meta tags:
description=Why interface evolution with default methods does not work for whole interfaces - at least not smooth enough to be practical.;
keywords=interface evolution;

Headings (most frequently used words):

the, interface, methods, interfaces, evolving, evolution, with, default, part, ii, problem, statement, idea, roadblock, possible, detours, reflection, wildcards, specialized, classes, instances, adapters, for, containers, screw, it,

Text of the page (most frequently used words):
the (147), #interface (45), java (42), new (41), code (39), this (33), old (30), and (27), methods (26), you (23), with (22), version (22), for (21), can (19), that (18), project (16), container (15), default (14), interfaces (14), use (14), not (13), all (13), which (13), are (12), your (12), published (11), client (11), but (11), how (10), instances (10), generics (10), post (10), release (9), from (9), implementations (9), return (9), calltointernalcode (9), evolving (8), their (8), some (7), problem (7), might (7), used (7), evolution (7), types (7), time (7), will (7), internal (7), clients (7), without (7), compile (7), errors (7), whole (6), idea (6), just (6), out (6), part (6), works (6), work (6), want (6), way (6), one (6), have (6), changes (6), now (6), where (6), license (5), good (5), look (5), using (5), reflection (5), replace (5), only (5), when (5), could (5), adapters (5), containers (5), possible (5), dosomething (5), get (5), requires (5), approach (5), change (5), they (5), junit (5), stackoverflow (4), why (4), even (4), transition (4), there (4), let (4), what (4), screw (4), next (4), them (4), check (4), asnew (4), classes (4), make (4), makes (4), wildcards (4), still (4), first (4), external (4), same (4), public (4), roadblock (4), update (4), well (4), really (4), community (4), github (3), doesn (3), like (3), three (3), individual (3), pretty (3), hard (3), back (3), into (3), collections (3), demo (3), over (3), libfx (3), allow (3), was (3), whether (3), specialized (3), also (3), see (3), solve (3), detours (3), must (3), adapted (3), step (3), remove (3), adapter (3), necessary (3), implementation (3), own (3), calls (3), ways (3), play (3), outline (3), has (3), move (3), contains (3), statement (3), follow (3), share (3), blog (3), pioneer (3), demos (3), streams (3), core (3), clean (3), privacy (2), rss (2), twitch (2), youtube (2), discord (2), mastodon (2), bluesky (2), though (2), saw (2), solution (2), trouble (2), while (2), single (2), principal (2), invariance (2), layer (2), done (2), smooth (2), reasons (2), creating (2), branch (2), spend (2), such (2), jdk (2), provide (2), essentially (2), call (2), down (2), depending (2), lets (2), instance (2), depends (2), pecs (2), after (2), don (2), general (2), cases (2), would (2), two (2), passed (2), breaks (2), assignments (2), value (2), does (2), least (2), ninstance (2), instead (2), because (2), far (2), method (2), returns (2), removes (2), implement (2), type (2), argument (2), ignoring (2), cause (2), follows (2), more (2), callers (2), declarations (2), sense (2), too (2), description (2), steps (2), read (2), library (2), then (2), ensure (2), valid (2), transitional (2), add (2), both (2), gradually (2), breaking (2), active (2), various (2), platforms (2), watch (2), space (2), notified (2), publish (2), content (2), around (2), yourself (2), repository (2), many (2), snippets (2), shown (2), permissive (2), reuse (2), projects (2), showcasing (2), important (2), features (2), src (2), source (2), about (2), talks (2), record (2), args (2), var (2), turn (2), year (2), tools (2), techniques (2), switch (2), serialization (2), records (2), valhalla (2), panama (2), loom (2), leyden (2), amber (2), performance (2), patterns (2), pattern (2), matching (2), optional (2), ramp (2), migration (2), meta (2), maven (2), libraries (2), lambda (2), javafx (2), basics (2), j_ms (2), dop (2), documentation (2), deprecation (2), libs (2), architecture (2), tags (2), javascript (2), contact, imprint, did, overlook, something, stupid, leave, comment, approaches, tackled, stood, end, worth, reiterated, sequence, fails, replacing, parametric, prevents, adapting, renaming, moving, most, simple, search, anyways, point, opinion, matter, long, deal, seems, become, pain, unless, introduce, complexity, sort, keep, fixing, things, before, merging, everything, master, unrelated, reason, currently, working, transformations, contain, curious, already, those, may, push, updated, sound, either, concrete, massaged, choose, class, situation, produce, advice, maximum, remember, http, com, 2723397, 2525313, banging, head, against, wall, came, ideas, help, special, outset, felt, retrospect, actually, obvious, involved, maybe, should, tried, damn, leads, problems, impossible, propagated, due, break, adapt, generally, create, hand, accepts, crucial, piece, presented, called, compatible, manner, glossed, details, hope, believe, come, stop, implementing, explicitly, second, additionally, handy, invoke, itself, starting, changed, returned, start, declaring, passing, temporarily, interact, through, extends, declare, converted, parameterized, owns, little, complicated, distinguish, seemed, lot, case, sat, interested, detailed, these, earlier, residues, given, her, wisely, made, releasing, again, released, definition, combines, desired, arise, straight, forward, usually, consists, less, announcing, had, specific, going, chance, achieving, define, phase, coexist, need, another, note, requirement, largely, place, wanted, tell, fix, resulting, highly, coupled, yours, separate, life, right, nice, guy, gal, requiring, flag, day, give, opportunity, until, any, substantially, rename, revamp, expressed, equivalent, provided, other, assume, base, imaginable, course, arguments, values, exactly, know, rest, ended, expect, much, great, incentive, reading, unfortunate, summary, couldn, explained, foolishly, announced, future, mini, series, were, introduced, enable, backwards, compatibility, sacrosanct, limited, adding, exclusive, expected, evolve, causing, thus, giving, toc, table, contents, lic, artist, dev, enough, practical, 2015, slides, upcoming, past, schedule, recordings, virtual, threads, vector, structured, concurrency, lilliput, galahad, babylon, openjdk, conversation, book, club, videos, jms, newsletter, posts, testing, rant, jigsaw, jdeps, impulse, lang, review, comments, words, site, better, enabled, nipafx,


Text of the page (random words):
interface evolution with default methods part ii interfaces nipafx this site works well without javascript but it works even better with javascript enabled bluesky mastodon discord youtube twitch github stackoverflow rss words tags architecture clean code clean comments code review collections community core lang core libs default methods deprecation documentation dop generics impulse j_ms java 10 java 11 java 12 java 13 java 16 java 17 java 18 java 20 java 23 java 24 java 25 java 26 java 27 java 8 java 9 java basics java next javafx jdeps js junit 5 junit pioneer lambda libfx libraries maven meta migration on ramp optional pattern matching patterns performance project amber project jigsaw project leyden project loom project panama project valhalla rant record args records reflection serialization streams switch techniques testing tools turn of the year var blog posts newsletter the jms videos tags ai architecture book club clean code collections community conversation core libs deprecation documentation dop generics j_ms java 10 java 11 java 12 java 16 java 17 java 18 java 19 java 21 java 22 java 23 java 24 java 25 java 26 java 27 java 28 java 8 java 9 java basics java next javafx junit 5 junit pioneer lambda libraries maven meta migration on ramp openjdk optional pattern matching patterns performance project amber project babylon project galahad project leyden project lilliput project loom project panama project valhalla records reflection serialization streams structured concurrency switch techniques tools turn of the year var vector virtual threads recordings streams schedule code demos demos demos junit pioneer record args libfx talks my talks past upcoming slides about about me license privacy 2015 04 10 interface evolution with default methods part ii interfaces post default methods generics java 8 why interface evolution with default methods does not work for whole interfaces at least not smooth enough to be practical src source dev artist lic license interface evolution with default methods part ii interfaces source code want to play around with the code yourself check out the repository java x demo a project showcasing all important java 9 16 features it contains many of the snippets shown in this blog post it has a permissive license so you can reuse the code for your projects table of contents the problem statement the idea evolving interface methods evolving the interface the roadblock possible detours wildcards specialized interfaces classes instances adapters for containers screw it reflection share follow share this post with your community i m active on various platforms watch this space or follow me there to get notified when i publish new content src want to play around with the code yourself check out the repository java x demo a project showcasing all important java 9 16 features it contains many of the snippets shown in this blog post it has a permissive license so you can reuse the code for your projects toc the problem statement the idea evolving interface methods evolving the interface the roadblock possible detours wildcards specialized interfaces classes instances adapters for containers screw it reflection s f share this post with your community i m active on various platforms watch this space or follow me there to get notified when i publish new content default methods were introduced to enable interface evolution if backwards compatibility is sacrosanct this is limited to adding new methods to interfaces which is their exclusive use in the jdk but if clients are expected to update their code default methods can be used to gradually evolve interfaces without causing compile errors thus giving clients time to update their code to a new version of the interface the first part of this mini series explained how default implementations allow to add replace and remove methods without breaking client code i foolishly announced that a future post will look into ways to replace whole interfaces also without breaking client code well you re reading this post now and the unfortunate summary is i couldn t make it work why generics why exactly you really want to know well read on then but the rest of the post is really only a description of how i ended up at a roadblock so don t expect too much of it great incentive eh the problem statement this is what we want to do assume your code base contains an interface which your clients use in all imaginable ways they have their own implementations call your code with instances of it and your code returns such instances and of course they use it as types for arguments and return values now you want to substantially change the interface rename it move it or revamp it in a way that can not be expressed with changes to individual methods but both interfaces are still equivalent in the sense that adapters can be provided to get from one version to the other you could just do it release a new version with the changes and tell your clients to fix their resulting compile errors if their code is highly coupled to yours they might have to do this in a separate branch to spend some time on it but that s life right you re a really nice guy gal though so instead of requiring a flag day you would like to give them the opportunity to change their code gradually over time e g until the next release without any compile errors note that this is the principal requirement for all that follows i m largely ignoring whether that s a good idea in the first place i just wanted to look how far i can get the only way i see to even have a chance of achieving this is to define a transitional phase where both the old and the new version of the interface coexist so what we really need is a general step by step approach of how to move implementations callers and declarations from one interface to another the idea when announcing this post i had a specific idea of how this was going to work it was essentially the same approach i used for methods evolving interface methods using default methods to add replace or remove single methods of an interface is pretty straight forward and usually consists of three steps in some cases less new version a new version of the library is released where the interface definition is transitional and combines the old as well as the new desired outline default methods ensure that all external implementations and calls are still valid and no compile errors arise on an update transition then the client has time to move from the old to the new outline again the default methods ensure that adapted external implementations and calls are valid and the changes are possible without compile errors new version in a new version the library removes residues of the old outline given the client used her time wisely and made the necessary changes releasing the new version will not cause compile errors if you are interested in a more detailed description of these steps you can read my earlier post evolving the interface this approach seemed to make a lot of sense for this case too so i sat down to play it out it is a little more complicated if the whole interface changes because where methods only have callers and implementations the interface is also a type i e it can be used in declarations this makes it necessary to distinguish three ways to use the interface internal use where you own the implementation and the code using the interface published use where you own the implementation but the client makes calls to the code external use where the client owns the implementation and the code using the interface the part that works follows the same approach as evolving methods new version release a new version with the new interface which extends the old one let all internal code implement and use the new interface all published code will use the old interface to declare argument types and the new interface for return types if instances have to be converted this can be done with an adapter ignoring parameterized types for now this change will not cause compile errors in client code transition after the release the clients change their code starting with the implementations of the old interface which are changed to implement the new one and the instances returned by your published code they can start declaring instances of the new type update the argument types of methods they are passing them to and so on if necessary the adapter can be used temporarily to interact with old instances through the new interface new version release a version which removes the old interface in the same way as with evolving methods default implementations in the new interface allow client code to stop implementing the old interface explicitly which lets you remove it in the second release additionally a handy asnew method on the old interface can invoke the adapter to return itself adapted to the new interface i glossed over some of the details but i hope you believe me that this works now let s come back to generics the roadblock the crucial piece in the presented approach is the published code it is called by your clients so the first release must change it in a compatible manner and as all internal code requires the new interface it must make the step from old to new without generics it might look like this in version 0 public old dosomething old o calltointernalcode requires an old calltointernalcode o return o in version 1 the method still accepts old but returns new public new dosomething old o calltointernalcode now requires a new new n o asnew calltointernalcode n return n ok so far so good now let s see how that might look with generics in version 0 public container old dosomething container old o calltointernalcode requires a container old calltointernalcode o return o in version 1 doesn t work because it breaks assignments of the return value public container new dosomething container old o calltointernalcode requires a container new but we can not hand an adapted version to calltointernalcode instead we must create a new container new ninstance o get asnew container new n container of ninstance calltointernalcode n return n so using the published layer of code to adapt from the old to the new interface does not generally work for at least two reasons due to the invariance of generics in java all assignments of the return value will break container old old works in version 0 breaks in version 1 container old o published dosomething old the same container instance can not be passed from the published to the internal code this leads to two problems creating a new container might be hard or impossible changes the internal code makes to the new container are not propagated to the container passed by the external code damn from the outset on i felt that generics would be trouble in retrospect that s actually pretty obvious when types are involved how can generics not be a problem so maybe i should ve tried to solve the hard problem first possible detours after banging my head against the wall for a time i still don t see a general way to solve this but i came up with some ideas which might help solve special cases wildcards you could check whether the published and internal code makes maximum use of wildcards remember pecs http stackoverflow com q 2723397 2525313 what is pecs stackoverflow you could also advice your clients on how to use them depending on the situation this might produce a solution specialized interfaces classes instances depending on the concrete code it could be possible to provide a new version of the published interfaces classes or instances which use the old interface if the code can be massaged in a way which lets the client choose whether to use the interface class or instance which depends on the old interface or the one which depends on the new interface the individual implementations do not have to make the transition but this may push the old interface back down into the internal code which was just updated to only use the new one that doesn t sound good either adapters for containers you could provide adapters for containers which are used with the old interface in published code this will essentially allow you to call asnew on those containers for an unrelated reason i m currently working on such transformations for some of the jdk collections the next version of libfx will contain them if you re curious you can already check out a demo over at github screw it all this and for what to keep the client from creating a branch spend some time fixing things there before merging everything back into master screw it at this point this is my opinion on the matter while interface evolution is smooth as long as you only deal with individual methods it seems to become a pain when you want to replace whole interfaces so unless there are pretty good reasons to introduce all this complexity i d just do it the hard way and let the client sort it out or not do it at all and if you re just renaming or moving an interface most or even all of the work can be done by a simple search replace anyways reflection we reiterated how default methods can be used for interface evolution with a three part sequence of release transition release while this works for single methods we saw that it fails for replacing whole interfaces the principal problem is that invariance of parametric types prevents us from using the published code as an adapting layer even though we saw some approaches how that problem might be tackled no good solution stood out in the end it doesn t look like it is worth the trouble did i overlook something or is the whole idea just stupid why not leave a comment bluesky mastodon discord youtube twitch github stackoverflow rss imprint privacy contact license
Images from subpage: "nipafx.dev/java-28/" Verify
Images from subpage: "nipafx.dev/openjdk/" Verify
Images from subpage: "nipafx.dev/project-babylon/" Verify
Images from subpage: "nipafx.dev/project-galahad/" Verify
Images from subpage: "nipafx.dev/project-lilliput/" Verify

Verified site has: 96 subpage(s). Do you want to verify them? Verify pages:

1-5 6-10 11-15 16-20 21-25 26-30 31-35 36-40 41-45 46-50
51-55 56-60 61-65 66-70 71-75 76-80 81-85 86-90 91-95 96-96


The site also has references to the 1 subdomain(s)

  slides.nipafx.dev  Verify


Top 50 hastags from of all verified websites.

Supplementary Information (add-on for SEO geeks)*- See more on header.verify-www.com

Header

HTTP/2 301
server GitHub.com
content-type text/html
location htt????/nipafx.dev/java-default-methods-interface-evolution-failure/
access-control-allow-origin *
expires Tue, 15 Sep 2026 04:38:54 GMT
cache-control max-age=600
x-proxy-cache MISS
x-github-request-id A126:31F094:1E978C9:1ECECFF:6AA8C981
x-github-edge-region fra
accept-ranges bytes
age 0
date Tue, 15 Sep 2026 04:28:54 GMT
via 1.1 varnish
x-served-by cache-rtm-ehrd2290027-RTM
x-cache MISS
x-cache-hits 0
x-timer S1789446535.790476,VS0,VE106
vary Accept-Encoding
x-fastly-request-id b595fb6d4f9713aaf34714b983a01cc2d74b4b4c
content-length 162
HTTP/2 200
server GitHub.com
content-type text/html; charset=utf-8
last-modified Tue, 15 Sep 2026 02:43:32 GMT
access-control-allow-origin *
etag W/ 6aa8b0d4-2e5a1
expires Tue, 15 Sep 2026 04:38:55 GMT
cache-control max-age=600
content-encoding gzip
x-proxy-cache MISS
x-github-request-id 1958:31F094:1E978EB:1ECED27:6AA8C985
x-github-edge-region fra
accept-ranges bytes
date Tue, 15 Sep 2026 04:28:55 GMT
via 1.1 varnish
age 0
x-served-by cache-rtm-ehrd2290027-RTM
x-cache MISS
x-cache-hits 0
x-timer S1789446535.904725,VS0,VE214
vary Accept-Encoding
x-fastly-request-id 47a539a38c7ea662708c5f6e8570e4d2da5d660a
content-length 47088

Meta Tags

title="Interface Evolution With Default Methods Part II: Interfaces // nipafx"
charset="utf-8"
http-equiv="x-ua-compatible" content="ie=edge"
name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"
name="generator" content="Gatsby 5.7.0"
data-react-helmet="true" name="description" content="Why interface evolution with default methods does not work for whole interfaces - at least not smooth enough to be practical."
data-react-helmet="true" name="twitter:card" content="summary_large_image"
data-react-helmet="true" name="twitter:site" content="@nipafx"
data-react-helmet="true" name="twitter:creator" content="@nipafx"
data-react-helmet="true" name="twitter:title" content="Interface Evolution With Default Methods – Part II: Interfaces // nipafx"
data-react-helmet="true" name="twitter:description" content="Why interface evolution with default methods does not work for whole interfaces - at least not smooth enough to be practical."
data-react-helmet="true" name="twitter:image" content="htt????/nipafx.dev/static/09fcd54a629c3d3c74adcdc9b571f35c/880e6/interface-evolution-with-default-methods-II.jpg"
data-react-helmet="true" name="keywords" content="interface evolution"
data-react-helmet="true" property="og:title" content="Interface Evolution With Default Methods – Part II: Interfaces // nipafx"
data-react-helmet="true" property="og:type" content="article"
data-react-helmet="true" property="og:image" content="htt????/nipafx.dev/static/09fcd54a629c3d3c74adcdc9b571f35c/880e6/interface-evolution-with-default-methods-II.jpg"
data-react-helmet="true" property="og:url" content="htt????/nipafx.dev/java-default-methods-interface-evolution-failure/"
data-react-helmet="true" property="og:description" content="Why interface evolution with default methods does not work for whole interfaces - at least not smooth enough to be practical."
data-react-helmet="true" property="og:site_name" content="nipafx // You. Me. Java."
name="theme-color" content="#69ea7d"

Load Info

page size189857
load time (s)0.481119
redirect count1
speed download97896
server IP 185.199.108.153
* all occurrences of the string "http://" have been changed to "htt???/"