SlideShare a Scribd company logo
@mirocupakDJUG
The good, the bad, and the ugly
of Java API design
Miro Cupak
Co-founder & VP Engineering, DNAstack
October 02, 2019
@mirocupakDJUG 2
Features
• Collections API.
• Stack-walking API.
• Process API.
• HTTP client API.
@mirocupakDJUG
Collections API
3
@mirocupakDJUG 4
Best practices
• Take advantage of convenience factory methods for collections.
• Immutable collections via of/ofEntries and copies via copyOf.
• Less verbose, no static initializer blocks.
• Create immutable collections by default, only add mutability when needed.
• No need to worry about forgetting references to underlying collections.
• Thread-safe and can be shared freely (no need for defensive copies).
• Good performance.
• Prefer collecting into immutable collections using toUnmodifiableList,
toUnmodifiableSet, toUnmodifiableMap.
• Use toArray to convert collections to arrays.
@mirocupakDJUG 5
Antipatterns
• Obtaining collections through other data structures (Arrays.asList,
Stream.of).
• Pulling in external dependencies only to obtain immutable collections (e.g.
Guava and its Immutable*).
• Instance-initializer construct in an anonymous inner class to instantiate
collections.
• Performance over clean APIs ([List, Set, Map].of).
@mirocupakDJUG 6
Patterns
• Static factory methods to create objects (of/ofEntries/copyOf).
• Name concisely (convention: of).
• Concrete classes not as part of the public API with static methods on
interfaces returning instances (pattern for implementation flexibility).
• Static import when readability not jeopardized (java.util.Map.entry).
• Tuple wrapper objects and convenience methods to generate them when
multiple varargs needed (Map.ofEntries).
• Converting between types via copyOf.
• Constructor reference as a generating function (array in a toArray call).
• Immutability by default (collections with copies and collectors).
@mirocupakDJUG
Stack-walking API
7
@mirocupakDJUG 8
Best practices
• Take advantage of the Stream API to access only certain elements.
• Be aware of StackWalker.Option.
• Don’t resolve classes manually.
• Use to show hidden and reflection frames.
@mirocupakDJUG 9
Antipatterns
• Using [Thread, Throwable].getStackTrace() to traverse selected
frames of the execution stack.
• Treating execution stack as text.
• Using strings to represent Class instances.
• Accessing things eagerly when only parts of them are needed.
• Surprising hidden method behaviour (omitting elements of the stack for
performance).
@mirocupakDJUG 10
Patterns
• Collections over arrays.
• Leveraging Stream API in API design.
• Choose suitable represetations (don’t model everything as strings).
• Good performance through lazy access via streams.
• Methods accepting functions on streams as parameters to maintain
consistent state and control (walk()).
• Obtaining configured instances via static factory methods parameterized
with enums (getInstance()).
• Work with a security manager (secure access to Class objects).
• Permission checks when constructing instead of using an object.
@mirocupakDJUG
Process API
11
@mirocupakDJUG 12
Best practices
• ProcessHandle is a clean way of obtaining information about processes.
• Take advantage of convenience methods: pid, info, command…
• Trigger actions on process termination via onExit.
• Connect ProcessBuilder with ProcessHandle via toHandle.
@mirocupakDJUG 13
Antipatterns
• Accessing process information via MXBeans or OS utilities.
• Pulling in external libraries for simple process management (e.g. Apache
Commons Exec).
• Incomplete APIs - providing functionality to start hard-to-manage resources
without providing the functionality to obtain information about them.
• APIs leading the clients to use non-portable constructs.
@mirocupakDJUG 14
Patterns
• Providing convenience methods for commonly used functionality.
• Compact fluent API to access nested information.
• Nested public interfaces to group and organize (ProcessHandle.Info).
• Using convenient static factory methods to obtain instances
(ProcessHandle.[current, of, allProcesses]).
• Returning streams instead of collections to streamline lazy processing of
many elements (allProcesses, children, descendants…).
• Returning CompletableFuture instances in asynchronous APIs
(onExit).
• Providing adapters via to* methods (toHandle).
@mirocupakDJUG
HTTP client API
15
@mirocupakDJUG 16
Best practices
• Clear organization: HttpClient, HttpRequest, HttpResponse.
• HttpURLConnection is not pleasant to use.
• The new client API is versatile, flexible and clean.
• Prefer functionality in the JDK to external libraries.
@mirocupakDJUG 17
Antipatterns
• Using HttpURLConnection directly.
• Inconsistent capitalization (HttpURLConnection).
• Overly abstract and general APIs (URLConnection).
• Unclear conceptual API model (URL).
• Type casting needed to obtain the right instance (openConnection).
• Using strings where methods or enums would be more practical
(setRequestMethod(“GET”)).
• Requiring the client to use I/O boilerplate (BufferedReader/
InputStreamReader/InputStream…).
@mirocupakDJUG 18
Antipatterns
• Mandatory blocking network I/O.
• Side effects and hidden assumptions (getInputStream).
• Inconsistent behaviour across APIs (URLConnection vs. Socket).
@mirocupakDJUG 19
Patterns
• Clear separation of concepts at the class level (HttpClient,
HttpRequest, HttpResponse).
• Builder.
• Asynchronous via CompletableFuture.
• Clear and consistent naming.
• Convenience methods to access commonly used features (statusCode,
body).
@mirocupakDJUG
Questions?
20

More Related Content

PDF
The good, the bad, and the ugly of Java API design
PDF
The good, the bad, and the ugly of Java API design
PDF
The good, the bad, and the ugly of Java API design
PDF
The Good, the Bad and the Ugly of Java API design
PDF
BigDataSpain 2016: Stream Processing Applications with Apache Apex
PPTX
AngularJS 1.x - your first application (problems and solutions)
PDF
Hibernate performance tuning
PDF
(ATS6-DEV01) What’s new for Protocol and Component Developers in AEP 9.0
The good, the bad, and the ugly of Java API design
The good, the bad, and the ugly of Java API design
The good, the bad, and the ugly of Java API design
The Good, the Bad and the Ugly of Java API design
BigDataSpain 2016: Stream Processing Applications with Apache Apex
AngularJS 1.x - your first application (problems and solutions)
Hibernate performance tuning
(ATS6-DEV01) What’s new for Protocol and Component Developers in AEP 9.0

What's hot (9)

PPTX
Parallel Programming
PDF
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
PDF
Breathing new life into Apache Oozie with Apache Ambari Workflow Manager
PDF
Gradle - Build System
PDF
Creating Modular Test-Driven SPAs with Spring and AngularJS
PDF
Reactive Streams
PDF
Training Slides: 303 - Replicating out of a Cluster
PDF
The Spring Update
PPTX
Spring batch introduction
Parallel Programming
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
Breathing new life into Apache Oozie with Apache Ambari Workflow Manager
Gradle - Build System
Creating Modular Test-Driven SPAs with Spring and AngularJS
Reactive Streams
Training Slides: 303 - Replicating out of a Cluster
The Spring Update
Spring batch introduction
Ad

Similar to The good, the bad, and the ugly of Java API design (20)

PPTX
Practices and Tools for Building Better APIs
ODT
Designing Better API
PDF
Clean code with Java 9
PPT
How to design effective APIs
PDF
Voxxed Athens 2018 - Clean Code with Java9+
PDF
Writing clean code with Java 9+
PPTX
Golden Rules of API Design
PPTX
How to define an api
PDF
Practices and tools for building better API (JFall 2013)
PDF
Practices and tools for building better APIs
PPTX
How to build Sdk? Best practices
PPT
Api desgin
PDF
Training Semester Report, Api Types of Apps
PDF
How to design good api
PDF
ApiDesign
PDF
API design
PPTX
API-first development
PPTX
Lessons learned on the Azure API Stewardship Journey.pptx
PDF
How To Design A Good A P I And Why It Matters G O O G L E
PDF
Extracting Examples for API Usage Patterns
Practices and Tools for Building Better APIs
Designing Better API
Clean code with Java 9
How to design effective APIs
Voxxed Athens 2018 - Clean Code with Java9+
Writing clean code with Java 9+
Golden Rules of API Design
How to define an api
Practices and tools for building better API (JFall 2013)
Practices and tools for building better APIs
How to build Sdk? Best practices
Api desgin
Training Semester Report, Api Types of Apps
How to design good api
ApiDesign
API design
API-first development
Lessons learned on the Azure API Stewardship Journey.pptx
How To Design A Good A P I And Why It Matters G O O G L E
Extracting Examples for API Usage Patterns
Ad

More from Miro Cupak (20)

PDF
Exploring the latest and greatest from Java 14
PDF
Exploring reactive programming in Java
PDF
Exploring the last year of Java
PDF
Local variable type inference - Will it compile?
PDF
Local variable type inference - Will it compile?
PDF
Exploring reactive programming in Java
PDF
Master class in modern Java
PDF
Exploring reactive programming in Java
PDF
Writing clean code with modern Java
PDF
Master class in modern Java
PDF
Exploring reactive programming in Java
PDF
Writing clean code with modern Java
PDF
Exploring what's new in Java 10 and 11 (and 12)
PDF
Exploring what's new in Java 10 and 11
PDF
Exploring what's new in Java in 2018
PDF
Reactive programming in Java
PDF
Master class in Java in 2018
PDF
Exploring reactive programming with Java
PDF
Exploring reactive programming in Java
PDF
Writing clean code with Java in 2018
Exploring the latest and greatest from Java 14
Exploring reactive programming in Java
Exploring the last year of Java
Local variable type inference - Will it compile?
Local variable type inference - Will it compile?
Exploring reactive programming in Java
Master class in modern Java
Exploring reactive programming in Java
Writing clean code with modern Java
Master class in modern Java
Exploring reactive programming in Java
Writing clean code with modern Java
Exploring what's new in Java 10 and 11 (and 12)
Exploring what's new in Java 10 and 11
Exploring what's new in Java in 2018
Reactive programming in Java
Master class in Java in 2018
Exploring reactive programming with Java
Exploring reactive programming in Java
Writing clean code with Java in 2018

Recently uploaded (20)

PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Digital Strategies for Manufacturing Companies
PPTX
Operating system designcfffgfgggggggvggggggggg
PPTX
Essential Infomation Tech presentation.pptx
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
Nekopoi APK 2025 free lastest update
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
top salesforce developer skills in 2025.pdf
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
CHAPTER 2 - PM Management and IT Context
Digital Strategies for Manufacturing Companies
Operating system designcfffgfgggggggvggggggggg
Essential Infomation Tech presentation.pptx
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Wondershare Filmora 15 Crack With Activation Key [2025
Navsoft: AI-Powered Business Solutions & Custom Software Development
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Nekopoi APK 2025 free lastest update
How to Choose the Right IT Partner for Your Business in Malaysia
Odoo POS Development Services by CandidRoot Solutions
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
top salesforce developer skills in 2025.pdf

The good, the bad, and the ugly of Java API design

  • 1. @mirocupakDJUG The good, the bad, and the ugly of Java API design Miro Cupak Co-founder & VP Engineering, DNAstack October 02, 2019
  • 2. @mirocupakDJUG 2 Features • Collections API. • Stack-walking API. • Process API. • HTTP client API.
  • 4. @mirocupakDJUG 4 Best practices • Take advantage of convenience factory methods for collections. • Immutable collections via of/ofEntries and copies via copyOf. • Less verbose, no static initializer blocks. • Create immutable collections by default, only add mutability when needed. • No need to worry about forgetting references to underlying collections. • Thread-safe and can be shared freely (no need for defensive copies). • Good performance. • Prefer collecting into immutable collections using toUnmodifiableList, toUnmodifiableSet, toUnmodifiableMap. • Use toArray to convert collections to arrays.
  • 5. @mirocupakDJUG 5 Antipatterns • Obtaining collections through other data structures (Arrays.asList, Stream.of). • Pulling in external dependencies only to obtain immutable collections (e.g. Guava and its Immutable*). • Instance-initializer construct in an anonymous inner class to instantiate collections. • Performance over clean APIs ([List, Set, Map].of).
  • 6. @mirocupakDJUG 6 Patterns • Static factory methods to create objects (of/ofEntries/copyOf). • Name concisely (convention: of). • Concrete classes not as part of the public API with static methods on interfaces returning instances (pattern for implementation flexibility). • Static import when readability not jeopardized (java.util.Map.entry). • Tuple wrapper objects and convenience methods to generate them when multiple varargs needed (Map.ofEntries). • Converting between types via copyOf. • Constructor reference as a generating function (array in a toArray call). • Immutability by default (collections with copies and collectors).
  • 8. @mirocupakDJUG 8 Best practices • Take advantage of the Stream API to access only certain elements. • Be aware of StackWalker.Option. • Don’t resolve classes manually. • Use to show hidden and reflection frames.
  • 9. @mirocupakDJUG 9 Antipatterns • Using [Thread, Throwable].getStackTrace() to traverse selected frames of the execution stack. • Treating execution stack as text. • Using strings to represent Class instances. • Accessing things eagerly when only parts of them are needed. • Surprising hidden method behaviour (omitting elements of the stack for performance).
  • 10. @mirocupakDJUG 10 Patterns • Collections over arrays. • Leveraging Stream API in API design. • Choose suitable represetations (don’t model everything as strings). • Good performance through lazy access via streams. • Methods accepting functions on streams as parameters to maintain consistent state and control (walk()). • Obtaining configured instances via static factory methods parameterized with enums (getInstance()). • Work with a security manager (secure access to Class objects). • Permission checks when constructing instead of using an object.
  • 12. @mirocupakDJUG 12 Best practices • ProcessHandle is a clean way of obtaining information about processes. • Take advantage of convenience methods: pid, info, command… • Trigger actions on process termination via onExit. • Connect ProcessBuilder with ProcessHandle via toHandle.
  • 13. @mirocupakDJUG 13 Antipatterns • Accessing process information via MXBeans or OS utilities. • Pulling in external libraries for simple process management (e.g. Apache Commons Exec). • Incomplete APIs - providing functionality to start hard-to-manage resources without providing the functionality to obtain information about them. • APIs leading the clients to use non-portable constructs.
  • 14. @mirocupakDJUG 14 Patterns • Providing convenience methods for commonly used functionality. • Compact fluent API to access nested information. • Nested public interfaces to group and organize (ProcessHandle.Info). • Using convenient static factory methods to obtain instances (ProcessHandle.[current, of, allProcesses]). • Returning streams instead of collections to streamline lazy processing of many elements (allProcesses, children, descendants…). • Returning CompletableFuture instances in asynchronous APIs (onExit). • Providing adapters via to* methods (toHandle).
  • 16. @mirocupakDJUG 16 Best practices • Clear organization: HttpClient, HttpRequest, HttpResponse. • HttpURLConnection is not pleasant to use. • The new client API is versatile, flexible and clean. • Prefer functionality in the JDK to external libraries.
  • 17. @mirocupakDJUG 17 Antipatterns • Using HttpURLConnection directly. • Inconsistent capitalization (HttpURLConnection). • Overly abstract and general APIs (URLConnection). • Unclear conceptual API model (URL). • Type casting needed to obtain the right instance (openConnection). • Using strings where methods or enums would be more practical (setRequestMethod(“GET”)). • Requiring the client to use I/O boilerplate (BufferedReader/ InputStreamReader/InputStream…).
  • 18. @mirocupakDJUG 18 Antipatterns • Mandatory blocking network I/O. • Side effects and hidden assumptions (getInputStream). • Inconsistent behaviour across APIs (URLConnection vs. Socket).
  • 19. @mirocupakDJUG 19 Patterns • Clear separation of concepts at the class level (HttpClient, HttpRequest, HttpResponse). • Builder. • Asynchronous via CompletableFuture. • Clear and consistent naming. • Convenience methods to access commonly used features (statusCode, body).