diff --git a/src/main/java/tools/jackson/databind/ObjectMapper.java b/src/main/java/tools/jackson/databind/ObjectMapper.java
index 97732c13a0..c1cfb4e47f 100644
--- a/src/main/java/tools/jackson/databind/ObjectMapper.java
+++ b/src/main/java/tools/jackson/databind/ObjectMapper.java
@@ -7,6 +7,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
@@ -2230,6 +2231,45 @@ public ObjectReader readerForMapOf(Class> type) {
null, _injectableValues);
}
+ /**
+ * Factory method for constructing {@link ObjectReader} that will
+ * read or update instances of auto-detected type; inferred from compiled
+ * info. Note that the nominal parameter MUST be an empty array;
+ * otherwise an exception will be thrown.
+ * Usage:
+ *
+ * MyType result = objectMapper.readerForDetectedType().readValue(json);
+ *
+ *
+ * @since 3.0
+ */
+ public ObjectReader readerForDetectedType(T... reified) {
+ // Should be auto-generated empty array; verify
+ Objects.requireNonNull(reified, "reified");
+ if (reified.length != 0) {
+ throw new IllegalArgumentException(String.format(
+"argument \reified\" should be empty; has %d elements", reified.length));
+ }
+ Type type = _getClassOf(reified);
+System.err.println("DEBUG: reified type: "+type);
+ _assertNotNull("type", type);
+ return _newReader(deserializationConfig(), _typeFactory.constructType(type), null,
+ null, _injectableValues);
+ }
+
+ /**
+ * Utility method to get the class type from a varargs array.
+ *
+ * @param the generic type
+ * @param array the varargs array
+ * @return the class of the array component
+ *
+ * @since 3.0
+ */
+ private static Class _getClassOf(T[] array) {
+ return (Class) array.getClass().getComponentType();
+ }
+
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified {@link JsonNodeFactory} for constructing JSON trees.
diff --git a/src/test/java/tools/jackson/databind/ObjectReaderTest.java b/src/test/java/tools/jackson/databind/ObjectReaderTest.java
index 759f2f1890..a5ad12ebb1 100644
--- a/src/test/java/tools/jackson/databind/ObjectReaderTest.java
+++ b/src/test/java/tools/jackson/databind/ObjectReaderTest.java
@@ -90,7 +90,7 @@ public void testReaderForArrayOf() throws Exception
assertEquals(ABC.C, abcs[1]);
}
- // [databind#2693]: convenience read methods:
+ // [databind#2693]: convenience read methods
@Test
public void testReaderForListOf() throws Exception
{
@@ -100,7 +100,7 @@ public void testReaderForListOf() throws Exception
assertEquals(Arrays.asList(ABC.B, ABC.C), value);
}
- // [databind#2693]: convenience read methods:
+ // [databind#2693]: convenience read methods
@Test
public void testReaderForMapOf() throws Exception
{
@@ -110,6 +110,29 @@ public void testReaderForMapOf() throws Exception
assertEquals(Collections.singletonMap("key", ABC.B), value);
}
+ // [databind#5064]: auto-detection of type
+ @Test
+ public void testReaderForDetectedType() throws Exception
+ {
+ // First, regular "untyped" (java.lang.Object)
+ List ob = MAPPER.readerForDetectedType()
+ .readValue("[1]");
+ assertNotNull(ob);
+ assertEquals(1, ob.get(0));
+
+ // then simple pojo
+ Point point = MAPPER.readerForDetectedType().readValue("{\"x\":1,\"y\":2}");
+ assertNotNull(point);
+ assertEquals(1, point.x);
+ assertEquals(2, point.y);
+
+ // and more complex
+ POJO pojo = MAPPER.readerForDetectedType().readValue("{\"name\":{\"value\":123}}");
+ assertNotNull(pojo);
+ assertNotNull(pojo.name);
+ assertEquals(Map.of("value", 123), pojo.name);
+ }
+
/*
/**********************************************************
/* Test methods, some alternative JSON settings