Diamond

A Java project that extends reflection making it really easy to use. "Where your reflection shines best!"

Лицензия

Лицензия

Группа

Группа

info.kfgodel
Идентификатор

Идентификатор

diamond
Последняя версия

Последняя версия

2.0.0
Дата

Дата

Тип

Тип

jar
Описание

Описание

Diamond
A Java project that extends reflection making it really easy to use. "Where your reflection shines best!"
Ссылка на сайт

Ссылка на сайт

https://github.com/kfgodel/diamond
Система контроля версий

Система контроля версий

https://github.com/kfgodel/diamond

Скачать diamond

Как подключить последнюю версию

<!-- https://jarcasting.com/artifacts/info.kfgodel/diamond/ -->
<dependency>
    <groupId>info.kfgodel</groupId>
    <artifactId>diamond</artifactId>
    <version>2.0.0</version>
</dependency>
// https://jarcasting.com/artifacts/info.kfgodel/diamond/
implementation 'info.kfgodel:diamond:2.0.0'
// https://jarcasting.com/artifacts/info.kfgodel/diamond/
implementation ("info.kfgodel:diamond:2.0.0")
'info.kfgodel:diamond:jar:2.0.0'
<dependency org="info.kfgodel" name="diamond" rev="2.0.0">
  <artifact name="diamond" type="jar" />
</dependency>
@Grapes(
@Grab(group='info.kfgodel', module='diamond', version='2.0.0')
)
libraryDependencies += "info.kfgodel" % "diamond" % "2.0.0"
[info.kfgodel/diamond "2.0.0"]

Зависимости

compile (3)

Идентификатор библиотеки Тип Версия
info.kfgodel : nary jar 3.0.0
com.google.guava : guava jar 28.1-jre
org.slf4j : slf4j-api jar 1.7.25

test (6)

Идентификатор библиотеки Тип Версия
info.kfgodel : jspek jar 1.0.0
ch.qos.logback : logback-core jar 1.2.3
ch.qos.logback : logback-classic jar 1.2.3
junit : junit jar 4.12
org.assertj : assertj-core jar 3.11.1
org.mockito : mockito-core jar 3.1.0

Модули Проекта

Данный проект не имеет модулей.

Diamond

Where your reflection shines better

A Java project with an alternative API to do reflection on java types in order to reduce verbosity, and offer a simple dsl for common cases.
It also adds some operations not possible with native reflection

Status: Experimental

API documentation

Every important method can be explored in the Full API guide here

Code Example

Every diamond abstraction over reflection is created with Diamond.of() which receives a native reflection object and adds a DSL over it.

Here are some examples on accessing fields, methods, and invoking them for a class

  it("adds a dsl over reflection API", () -> {
    final TypeInstance objectType = Diamond.of(Object.class);
    assertThat(objectType.names().canonicalName()).isEqualTo("java.lang.Object");
  });

  it("allows creating new instances without hassle", () -> {
    final Object createdObject = Diamond.of(Object.class)
      .newInstance();
    assertThat(createdObject).isNotNull();
  });

  it("offers a simplified no try-catch way to access class fields", () -> {
    final List<String> namesOfStringFields = Diamond.of(String.class)
      .fields().all()
      .map(TypeField::name)
      .collect(Collectors.toList());
    assertThat(namesOfStringFields).containsExactlyInAnyOrder(
      "value",
      "hash",
      "serialVersionUID",
      "serialPersistentFields",
      "CASE_INSENSITIVE_ORDER"
    );
  });

  it("offers a simplified no try-catch way to access class methods", () -> {
    final List<String> namesOfObjectMethods = Diamond.of(Object.class)
      .methods().all()
      .map(TypeMethod::name)
      .collect(Collectors.toList());
    assertThat(namesOfObjectMethods).containsExactlyInAnyOrder(
      "finalize",
      "wait",
      "wait",
      "wait",
      "equals",
      "toString",
      "hashCode",
      "getClass",
      "clone",
      "registerNatives",
      "notify",
      "notifyAll"
    );
  });

  it("offers a simplified way of calling constructors and methods",()->{
    final TypeConstructor constructor = Diamond.of(String.class)
      .constructors().withNativeParameterTypes(byte[].class)
      .unique().get();
    final String createdString = (String) constructor
      .invoke(new byte[0]);
    assertThat(createdString).isEmpty();
  });

Design principles

Working on this project I have tried to follow these design decisions in order to offer an intuitive and consistent API:

  • Don't use checked exceptions. Convert them to an specific runtime one:
    Most of the time, when working with reflection, you don't want to be bothered with security access, unlinked classes, missing methods, etc. And, if it fails, it's probably going to be a runtime problem. That allows you to avoid try-catching every time reflection is needed

  • Use Nary for returned elements:
    To reduce the number of available methods, but at the same time provide a flexible API I have used Nary when a method returns elements. This allows me to offer a single return type but you can treat it as an Optional or Stream at compile time. Because I don't know the classes you will be working on, the number of methods or fields may be predictable to you at compile time but not for me.

  • Reify the 2 hierarchies of a Java type: Compile & Runtime
    Java has 2 Type systems living in it. One that you see at compile time and probably think of it when coding, and the one that is available at runtime.
    For example, there are no instances of List at runtime, just List. Regardless of what the compiler complains about when you assign it to a List variable, at run time that's perfectly a legal operation.
    To deal with this 2 type systems I reified the compile time type hierarchy and the runtime hierarchy offering you access to both.
    However I prioritized the compile time type system over the runtime whenever I had to.

Версии библиотеки

Версия
2.0.0
1.0.5