GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - JunggiKim/java-refined: Refinement and functional value types for Java 8+

BranchesTags
Open more actions menu

Latest commit

 

History

60 Commits
60 Commits

Folders and files

NameName
Last commit message
Last commit date
.github
.github
 
 
compatibility
compatibility
 
 
config
config
 
 
docs
docs
 
 
gradle/wrapper
gradle/wrapper
 
 
java-refined-kotlin
java-refined-kotlin
 
 
src
src
 
 
.editorconfig
.editorconfig
 
 
.gitattributes
.gitattributes
 
 
.gitignore
.gitignore
 
 
CHANGELOG.md
CHANGELOG.md
 
 
CODE_OF_CONDUCT.md
CODE_OF_CONDUCT.md
 
 
CONTRIBUTING.md
CONTRIBUTING.md
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 
SECURITY.md
SECURITY.md
 
 
build.gradle.kts
build.gradle.kts
 
 
gradle.properties
gradle.properties
 
 
gradlew
gradlew
 
 
gradlew.bat
gradlew.bat
 
 
settings.gradle.kts
settings.gradle.kts
 
 

Repository files navigation

Java Refined

CI License Maven Central Coverage Mutation

Move validation into the type system. Zero runtime dependencies. Java 8+.

Why

Validated wrapper types are not a new idea — but existing JVM tools only give you the pattern, not the types themselves.

Tool What it provides Pre-built types
Jakarta Bean Validation Annotations (@NotNull, @Min) — checked only when validate() is called 0
VAVR Validation<E,A> monad — great error accumulation, but the validated value is still just Integer 0
Arrow-kt Smart-constructor pattern via Exact<A,B> — ~10 lines of boilerplate per type 0
Kotlin value class Language feature — you write everything yourself, Kotlin-only 0

java-refined ships 123+ ready-to-use types. PositiveInt, NonBlankString, EmailString — import and go. Zero dependencies. Java 8+.

Before

public void createUser(String name, int age, List<String> roles) {
    if (name == null || name.trim().isEmpty()) {
        throw new IllegalArgumentException("name must not be blank");
    }
    if (age <= 0) {
        throw new IllegalArgumentException("age must be positive");
    }
    if (roles == null || roles.isEmpty()) {
        throw new IllegalArgumentException("roles must not be empty");
    }
    // business logic ...
}

After

public void createUser(NonBlankString name, PositiveInt age, NonEmptyList<String> roles) {
    // no validation needed — the types guarantee it
}

Types replace scattered if-checks. Invalid data cannot even reach your method.

Quick Start

// Trusted data — just unwrap
PositiveInt confirmedAge = PositiveInt.unsafeOf(18);

// Untrusted input — safe fallback
PositiveInt safeAge = PositiveInt.ofOrElse(userInput, 1);
// Branch on success/failure
EmailString.of(email).fold(
    error -> badRequest(error.message()),
    valid -> ok(register(valid))
);

Kotlin Support

Optional module with Kotlin-idiomatic extensions:

import io.github.junggikim.refined.kotlin.*

val name = "Ada".toNonBlankStringOrThrow()
val tags = listOf("java", "fp").toNonEmptyListOrThrow()
// Safe fallback
val safeAge = PositiveInt.ofOrElse(input, 1)
// Kotlin-idiomatic nullable
val age = PositiveInt.of(input).getOrNull() ?: PositiveInt.unsafeOf(1)
// Convert to kotlin.Result
val result: Result<PositiveInt> = PositiveInt.of(input).toResult()

API

All refined wrappers follow the same pattern:

  • of(value) — returns Validation<Violation, T>, never throws
  • unsafeOf(value) — throws RefinementException on invalid input
  • ofOrElse(value, default) — returns validated instance or falls back to default
  • ofStream(stream) — collection wrappers only

Collection refined types implement JDK interfaces directly — NonEmptyList<T> is a List<T>, NonEmptyMap<K,V> is a Map<K,V>. No unwrapping needed.

For AI-Assisted Development

Method signatures are contracts that AI agents cannot ignore.

When your API accepts PositiveInt instead of int, code generators and AI assistants are forced to provide validated values — no scattered if-checks to forget or duplicate.

Installation

"I can just implement this myself. Why add a dependency?"

Totally fair! Copy the source into your project — it's MIT licensed. But if it saved you some time... give me a ⭐ 🥺

Published to Maven Central. Kotlin/JVM users can optionally add java-refined-kotlin for extension functions (adds kotlin-stdlib dependency).

Gradle Kotlin DSL

dependencies {
    implementation("io.github.junggikim:java-refined:1.1.0")

    // optional: Kotlin extensions
    // implementation("io.github.junggikim:java-refined-kotlin:1.1.0")
}

Maven

<dependency>
  <groupId>io.github.junggikim</groupId>
  <artifactId>java-refined</artifactId>
  <version>1.1.0</version>
</dependency>

Supported Types

Category Examples Count
Numeric PositiveInt, NegativeLong, NonZeroDouble, ZeroToOneFloat 46
Character DigitChar, LetterChar, UpperCaseChar 7
String NonBlankString, EmailString, UuidString, Ipv4String, JwtString 48
Collection NonEmptyList, NonEmptySet, NonEmptyMap, NonEmptyDeque, NonEmptyNavigableMap, ... 10
Control Option, Either, Try, Ior, Validated 5
Predicates GreaterThan, LengthBetween, MatchesRegex, AllOf, ForAllElements 55+

Full list: docs/type-matrix.md

Docs

  • Type Matrix
  • Compatibility
  • Kotlin Support Policy

Contributing

CONTRIBUTING.md · CODE_OF_CONDUCT.md · SECURITY.md

License

MIT. See LICENSE.

About

Refinement and functional value types for Java 8+

Topics

functional-programmingjavajava8maven-centralnon-emptyrefinement-typesvalidation

Resources

Readme
MIT license

Code of conduct

Code of conduct

Contributing

Contributing

Security policy

Security policy
Activity

Stars

10 stars

Watchers

0 watching

Forks

0 forks
Report repository

Releases

Packages

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.