kfgodel / diamond

A java project to extend reflection and make it easy to use
Apache License 2.0
0 stars 0 forks source link

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: