ljv
ljv copied to clipboard
Empty arrays?
Object[] array = {};
browse(new LJV(), array);
Graphviz Online doesn't render and reports an error:
in label of node n1
Hi @orionll , thanks for pointing this out!
Another thing I don't like about arrays now is that their type isn't shown.
I see two possibilities for array visualization fix:
- Use
xlabel
for array type, useshape="point"
, or circled{}
for an empty array
Pros: arrays are distinguishable from other objects. Cons: xlabel
is often poorly placed.
- Use first
<td>
for an array type, other<td>
s for array elements.
Pros: simplicity. Cons: array can be confused with other objects
What do you think?
I definitely like the second option the best:
- It solves the problem with empty arrays.
- Exact types give more information to viewers (e.g. make
int[]
vsbyte[]
arrays distinguishable). - This is better for pedagogical reasons: an array looks more or less like it's actually stored in JVM (the
Foo[]
part looks like an array header and then values are following).
I also think we should give users the full flexibility of how objects headers are represented as strings. There can be some method like:
// probably not the best name for the method
public <T> LJV setStringRepresentation(Class<T> cz, Function<T, String> function) {
...
}
Having this method, I can draw a graph like I want. For example, this is the default representation:
var list = new ArrayList<>();
list.add(1);
list.add(2);
new LJV()
.setTreatAsPrimitive(Integer.class)
.setStringRepresentation(List.class, list -> list.getClass().getSimpleName());
With a full package name and identity:
...
.setStringRepresentation(List.class, list -> list.getClass().getName() + "@" + System.identityHashCode(list))
String example:
...
.setStringRepresentation(String.class, str -> str)
.setByteStringRepresentation(b -> "0x" + Integer.toHexString(Byte.toUnsignedInt(b)))
I can create a separate task if you like this proposal.
-
Hi, concerning array visualization design: agreed, first
<td>
must contain the array type. We will implement it this way. -
Concerning the string representation: yes, I believe this idea deserves a separate Github issue. To begin with, I'd say that inventing a good design for it must be a difficult task:
- Should it be class-based, as you proposed, or object-based or even field-based (that is, what if we want to have a hexadecimal representation for a
byte
only when it's a specific field of a specific object, and decimal representation for all the other cases?) - Can we implement it in the spirit of attribute providers?
- Maybe we should globally refactor LJV first? (btw -- our next big aim is to use JOL instead of Reflection API for LJV)
- Should it be class-based, as you proposed, or object-based or even field-based (that is, what if we want to have a hexadecimal representation for a
I created #30. I looked at attributes providers. For me, they don't look like a suitable solution for this (but I may be wrong). I think we need a new type of provider (ObjectLabelProvider). In the future, we can add other types of providers (e.g. FieldLabelProvider).
I like the idea of using JOL for more precise visualization of objects graphs (exact order of fields, object sizes...). However, I think LJV should stay reflection-based by default and JOL should be an optional plugin (probably even in a separate module).
Hi @orionll ! An update 3 years later: finally project LJV now is the part of JOL and I am able to continue maintaining it as a part of JOL (before that it was not possible or reasonable, as introspection via reflection is not working in modern Java). This ticket is the first thing we are fixing :-)
Closed by https://github.com/openjdk/jol/pull/57