Java: Dynamic Type Contraints
up vote
0
down vote
favorite
I'm currently working on a protocol handler for a project of mine in Java. I am trying to create a maintainable and extensible API, meaning I do not want to simply hardcode in supported value types.
I have begun designing a 'protocol handler' that given a value (of a supported type) can encode that value according to the specification of the protocol, without the client worrying about the details of the translation process.
Different value types e.g. Strings or Integers necessarily have different encoding processes, but I don't want clients to worry about holding references to a different object for each possible type they may need to encode - as I said I don't want them to worry about the details.
So far I have defined a 'generic' DynamicHandler class that maintains a collection of 'specific' type aware StaticHandlers:
class DynamicHandler
{
Map<Class, StaticHandler> handlers;
<T> void handle(T value)
{
if(handlers.containsKey(value.class))
handlers.get(value.getType()).handle(value);
}
void <T> register(StaticHandler<T> handler)
{
handlers.put(T.class, handler);
}
}
The idea of this class is that a client simply passes a value they want to encode to the handle method and the DynamicHandler looks up and delegates to the StaticHandler.
interface StaticHandler<T>
{
void handle(T value);
}
Here an example of some client that uses this system:
class StringHandler implements StaticHandler<String>
{
void handle(String value)
{
...
}
}
DynamicHandler handler = new DynamicHandler();
handler.register(new StringHandler());
handler.handle("Hello World!");
I have two questions which I am struggling to find an answer to on my own:
- In the
DynamicHandler.registermethod, how can I get the type of T without having an instance of T? - Is it possible to implement the DynamicHandler type as a java.util.Map, in order to maximise compatibility with any 3rd party code clients, may use to build or otherwise process such objects?
Edit: Since DynamicHandler is essentially a Map, albeit with some generic trickery going on, is it possible to implement it as: DynamicHandler implements java.util.Map<...,...> (I'm not exactly sure what the Key and Value types should be here).
This is my first time asking a question on here, so I hope that I have been clear enough for you all. If there is anything you think needs clarifying just let me know and I will try my best.
java dictionary generics
New contributor
Matt Mead is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
|
show 1 more comment
up vote
0
down vote
favorite
I'm currently working on a protocol handler for a project of mine in Java. I am trying to create a maintainable and extensible API, meaning I do not want to simply hardcode in supported value types.
I have begun designing a 'protocol handler' that given a value (of a supported type) can encode that value according to the specification of the protocol, without the client worrying about the details of the translation process.
Different value types e.g. Strings or Integers necessarily have different encoding processes, but I don't want clients to worry about holding references to a different object for each possible type they may need to encode - as I said I don't want them to worry about the details.
So far I have defined a 'generic' DynamicHandler class that maintains a collection of 'specific' type aware StaticHandlers:
class DynamicHandler
{
Map<Class, StaticHandler> handlers;
<T> void handle(T value)
{
if(handlers.containsKey(value.class))
handlers.get(value.getType()).handle(value);
}
void <T> register(StaticHandler<T> handler)
{
handlers.put(T.class, handler);
}
}
The idea of this class is that a client simply passes a value they want to encode to the handle method and the DynamicHandler looks up and delegates to the StaticHandler.
interface StaticHandler<T>
{
void handle(T value);
}
Here an example of some client that uses this system:
class StringHandler implements StaticHandler<String>
{
void handle(String value)
{
...
}
}
DynamicHandler handler = new DynamicHandler();
handler.register(new StringHandler());
handler.handle("Hello World!");
I have two questions which I am struggling to find an answer to on my own:
- In the
DynamicHandler.registermethod, how can I get the type of T without having an instance of T? - Is it possible to implement the DynamicHandler type as a java.util.Map, in order to maximise compatibility with any 3rd party code clients, may use to build or otherwise process such objects?
Edit: Since DynamicHandler is essentially a Map, albeit with some generic trickery going on, is it possible to implement it as: DynamicHandler implements java.util.Map<...,...> (I'm not exactly sure what the Key and Value types should be here).
This is my first time asking a question on here, so I hope that I have been clear enough for you all. If there is anything you think needs clarifying just let me know and I will try my best.
java dictionary generics
New contributor
Matt Mead is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Could you try to state your second question more clearly? I struggle to figure out what exactly you're asking here.
– ohlec
Nov 8 at 9:30
You can callgetClass()on the object passed in inDynamicHandler.handle()instead of usingobj.classwhich wouldn't compile. You presume ifnullis passed in, there should be nothing that you would need to handle, and there won't be any chance that an object matches with multiple keys from the map.
– Jai
Nov 8 at 9:38
@Jal My apologies, that was actually just a mistake in my code. I updated it to used getClass() instead. I also clarified my first question to make it clear I want to know how to get the type of T in the register method.
– Matt Mead
Nov 8 at 9:45
@Ohlec I have edited my second question, hopefully it is clearer now.
– Matt Mead
Nov 8 at 9:45
@MattMead how do you imagine a client using this as a map? Isn'thandle()already the most convenient interface for this?
– ohlec
Nov 8 at 9:56
|
show 1 more comment
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm currently working on a protocol handler for a project of mine in Java. I am trying to create a maintainable and extensible API, meaning I do not want to simply hardcode in supported value types.
I have begun designing a 'protocol handler' that given a value (of a supported type) can encode that value according to the specification of the protocol, without the client worrying about the details of the translation process.
Different value types e.g. Strings or Integers necessarily have different encoding processes, but I don't want clients to worry about holding references to a different object for each possible type they may need to encode - as I said I don't want them to worry about the details.
So far I have defined a 'generic' DynamicHandler class that maintains a collection of 'specific' type aware StaticHandlers:
class DynamicHandler
{
Map<Class, StaticHandler> handlers;
<T> void handle(T value)
{
if(handlers.containsKey(value.class))
handlers.get(value.getType()).handle(value);
}
void <T> register(StaticHandler<T> handler)
{
handlers.put(T.class, handler);
}
}
The idea of this class is that a client simply passes a value they want to encode to the handle method and the DynamicHandler looks up and delegates to the StaticHandler.
interface StaticHandler<T>
{
void handle(T value);
}
Here an example of some client that uses this system:
class StringHandler implements StaticHandler<String>
{
void handle(String value)
{
...
}
}
DynamicHandler handler = new DynamicHandler();
handler.register(new StringHandler());
handler.handle("Hello World!");
I have two questions which I am struggling to find an answer to on my own:
- In the
DynamicHandler.registermethod, how can I get the type of T without having an instance of T? - Is it possible to implement the DynamicHandler type as a java.util.Map, in order to maximise compatibility with any 3rd party code clients, may use to build or otherwise process such objects?
Edit: Since DynamicHandler is essentially a Map, albeit with some generic trickery going on, is it possible to implement it as: DynamicHandler implements java.util.Map<...,...> (I'm not exactly sure what the Key and Value types should be here).
This is my first time asking a question on here, so I hope that I have been clear enough for you all. If there is anything you think needs clarifying just let me know and I will try my best.
java dictionary generics
New contributor
Matt Mead is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
I'm currently working on a protocol handler for a project of mine in Java. I am trying to create a maintainable and extensible API, meaning I do not want to simply hardcode in supported value types.
I have begun designing a 'protocol handler' that given a value (of a supported type) can encode that value according to the specification of the protocol, without the client worrying about the details of the translation process.
Different value types e.g. Strings or Integers necessarily have different encoding processes, but I don't want clients to worry about holding references to a different object for each possible type they may need to encode - as I said I don't want them to worry about the details.
So far I have defined a 'generic' DynamicHandler class that maintains a collection of 'specific' type aware StaticHandlers:
class DynamicHandler
{
Map<Class, StaticHandler> handlers;
<T> void handle(T value)
{
if(handlers.containsKey(value.class))
handlers.get(value.getType()).handle(value);
}
void <T> register(StaticHandler<T> handler)
{
handlers.put(T.class, handler);
}
}
The idea of this class is that a client simply passes a value they want to encode to the handle method and the DynamicHandler looks up and delegates to the StaticHandler.
interface StaticHandler<T>
{
void handle(T value);
}
Here an example of some client that uses this system:
class StringHandler implements StaticHandler<String>
{
void handle(String value)
{
...
}
}
DynamicHandler handler = new DynamicHandler();
handler.register(new StringHandler());
handler.handle("Hello World!");
I have two questions which I am struggling to find an answer to on my own:
- In the
DynamicHandler.registermethod, how can I get the type of T without having an instance of T? - Is it possible to implement the DynamicHandler type as a java.util.Map, in order to maximise compatibility with any 3rd party code clients, may use to build or otherwise process such objects?
Edit: Since DynamicHandler is essentially a Map, albeit with some generic trickery going on, is it possible to implement it as: DynamicHandler implements java.util.Map<...,...> (I'm not exactly sure what the Key and Value types should be here).
This is my first time asking a question on here, so I hope that I have been clear enough for you all. If there is anything you think needs clarifying just let me know and I will try my best.
java dictionary generics
java dictionary generics
New contributor
Matt Mead is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Matt Mead is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited Nov 8 at 9:41
New contributor
Matt Mead is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked Nov 8 at 9:24
Matt Mead
33
33
New contributor
Matt Mead is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Matt Mead is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Matt Mead is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Could you try to state your second question more clearly? I struggle to figure out what exactly you're asking here.
– ohlec
Nov 8 at 9:30
You can callgetClass()on the object passed in inDynamicHandler.handle()instead of usingobj.classwhich wouldn't compile. You presume ifnullis passed in, there should be nothing that you would need to handle, and there won't be any chance that an object matches with multiple keys from the map.
– Jai
Nov 8 at 9:38
@Jal My apologies, that was actually just a mistake in my code. I updated it to used getClass() instead. I also clarified my first question to make it clear I want to know how to get the type of T in the register method.
– Matt Mead
Nov 8 at 9:45
@Ohlec I have edited my second question, hopefully it is clearer now.
– Matt Mead
Nov 8 at 9:45
@MattMead how do you imagine a client using this as a map? Isn'thandle()already the most convenient interface for this?
– ohlec
Nov 8 at 9:56
|
show 1 more comment
Could you try to state your second question more clearly? I struggle to figure out what exactly you're asking here.
– ohlec
Nov 8 at 9:30
You can callgetClass()on the object passed in inDynamicHandler.handle()instead of usingobj.classwhich wouldn't compile. You presume ifnullis passed in, there should be nothing that you would need to handle, and there won't be any chance that an object matches with multiple keys from the map.
– Jai
Nov 8 at 9:38
@Jal My apologies, that was actually just a mistake in my code. I updated it to used getClass() instead. I also clarified my first question to make it clear I want to know how to get the type of T in the register method.
– Matt Mead
Nov 8 at 9:45
@Ohlec I have edited my second question, hopefully it is clearer now.
– Matt Mead
Nov 8 at 9:45
@MattMead how do you imagine a client using this as a map? Isn'thandle()already the most convenient interface for this?
– ohlec
Nov 8 at 9:56
Could you try to state your second question more clearly? I struggle to figure out what exactly you're asking here.
– ohlec
Nov 8 at 9:30
Could you try to state your second question more clearly? I struggle to figure out what exactly you're asking here.
– ohlec
Nov 8 at 9:30
You can call
getClass() on the object passed in in DynamicHandler.handle() instead of using obj.class which wouldn't compile. You presume if null is passed in, there should be nothing that you would need to handle, and there won't be any chance that an object matches with multiple keys from the map.– Jai
Nov 8 at 9:38
You can call
getClass() on the object passed in in DynamicHandler.handle() instead of using obj.class which wouldn't compile. You presume if null is passed in, there should be nothing that you would need to handle, and there won't be any chance that an object matches with multiple keys from the map.– Jai
Nov 8 at 9:38
@Jal My apologies, that was actually just a mistake in my code. I updated it to used getClass() instead. I also clarified my first question to make it clear I want to know how to get the type of T in the register method.
– Matt Mead
Nov 8 at 9:45
@Jal My apologies, that was actually just a mistake in my code. I updated it to used getClass() instead. I also clarified my first question to make it clear I want to know how to get the type of T in the register method.
– Matt Mead
Nov 8 at 9:45
@Ohlec I have edited my second question, hopefully it is clearer now.
– Matt Mead
Nov 8 at 9:45
@Ohlec I have edited my second question, hopefully it is clearer now.
– Matt Mead
Nov 8 at 9:45
@MattMead how do you imagine a client using this as a map? Isn't
handle() already the most convenient interface for this?– ohlec
Nov 8 at 9:56
@MattMead how do you imagine a client using this as a map? Isn't
handle() already the most convenient interface for this?– ohlec
Nov 8 at 9:56
|
show 1 more comment
2 Answers
2
active
oldest
votes
up vote
0
down vote
accepted
If null values are not handled and that it is designed such that there would never be any value that belongs to multiple classes, then you could do this:
public class DynamicHandler {
Map<Class, StaticHandler> handlers;
public <T> void handle(T value) {
if(value != null) {
handlers.entrySet()
.stream()
.filter(entry ->
entry.getKey().isInstance(value))
.findAny()
.ifPresent(entry ->
entry.getValue().handle(value));
}
}
public void <T> register(StaticHandler<T> handler) {
handlers.put(handler.getHandlingClass(), handler);
}
}
interface StaticHandler<T>
{
void handle(T value);
Class<T> getHandlingClass();
}
public class StringHandler implements StaticHandler<String> {
@Override public void handle(String value) {
...
}
@Override public final Class<String> getHandlingClass() {
return String.class;
}
}
@Jal I am currently planning on ignoring null values, it seems to make little sense to 'encode' nothing for my intended use case. I think the code you provided is an elegant solution to my problem. I certainly missed the getHandlingClass() idea for the static handler, thanks!
– Matt Mead
Nov 8 at 10:18
@MattMead When it comes to designing API, there are definitely a lot of things to consider. Each approach has its own pros and cons. It's better to be aware of different approaches and then consider from there.
– Jai
Nov 9 at 1:43
add a comment |
up vote
0
down vote
- In the DynamicHandler class, how can I get the type of T without having an instance of T?
The common solution for this is to pass it a Class object:
void <T> register(StaticHandler<T> handler, Class<T> clazz)
{
handlers.put(clazz, handler);
}
Just as one example of this in a commonly used library: Gson does something similar to register JSON serializers for specific types with GsonBuilder.registerTypeHierarchyAdapter
Or with the same idea, add a method in StaticHandler that gives the class of T
– Sodala
Nov 8 at 9:34
@ohlec Thanks, I did wonder about this myself but was unsure if it was the best or most common way to go about it. It seemed a bit redundant for the client to explicitly specify the type as a parameter when it is implicit from T. I will look into doing it this way.
– Matt Mead
Nov 8 at 9:35
@Sodala I also wondered about this approach. I will try both and see which seems to fit better.
– Matt Mead
Nov 8 at 9:37
@MattMead it certainly looks redundant, but due to type erasure clients do need to explicitly provide the type in some way (weather in register or in another method does not really matter)
– ohlec
Nov 8 at 9:40
@Ohlec I see, thanks for the insight.
– Matt Mead
Nov 8 at 9:47
|
show 2 more comments
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
If null values are not handled and that it is designed such that there would never be any value that belongs to multiple classes, then you could do this:
public class DynamicHandler {
Map<Class, StaticHandler> handlers;
public <T> void handle(T value) {
if(value != null) {
handlers.entrySet()
.stream()
.filter(entry ->
entry.getKey().isInstance(value))
.findAny()
.ifPresent(entry ->
entry.getValue().handle(value));
}
}
public void <T> register(StaticHandler<T> handler) {
handlers.put(handler.getHandlingClass(), handler);
}
}
interface StaticHandler<T>
{
void handle(T value);
Class<T> getHandlingClass();
}
public class StringHandler implements StaticHandler<String> {
@Override public void handle(String value) {
...
}
@Override public final Class<String> getHandlingClass() {
return String.class;
}
}
@Jal I am currently planning on ignoring null values, it seems to make little sense to 'encode' nothing for my intended use case. I think the code you provided is an elegant solution to my problem. I certainly missed the getHandlingClass() idea for the static handler, thanks!
– Matt Mead
Nov 8 at 10:18
@MattMead When it comes to designing API, there are definitely a lot of things to consider. Each approach has its own pros and cons. It's better to be aware of different approaches and then consider from there.
– Jai
Nov 9 at 1:43
add a comment |
up vote
0
down vote
accepted
If null values are not handled and that it is designed such that there would never be any value that belongs to multiple classes, then you could do this:
public class DynamicHandler {
Map<Class, StaticHandler> handlers;
public <T> void handle(T value) {
if(value != null) {
handlers.entrySet()
.stream()
.filter(entry ->
entry.getKey().isInstance(value))
.findAny()
.ifPresent(entry ->
entry.getValue().handle(value));
}
}
public void <T> register(StaticHandler<T> handler) {
handlers.put(handler.getHandlingClass(), handler);
}
}
interface StaticHandler<T>
{
void handle(T value);
Class<T> getHandlingClass();
}
public class StringHandler implements StaticHandler<String> {
@Override public void handle(String value) {
...
}
@Override public final Class<String> getHandlingClass() {
return String.class;
}
}
@Jal I am currently planning on ignoring null values, it seems to make little sense to 'encode' nothing for my intended use case. I think the code you provided is an elegant solution to my problem. I certainly missed the getHandlingClass() idea for the static handler, thanks!
– Matt Mead
Nov 8 at 10:18
@MattMead When it comes to designing API, there are definitely a lot of things to consider. Each approach has its own pros and cons. It's better to be aware of different approaches and then consider from there.
– Jai
Nov 9 at 1:43
add a comment |
up vote
0
down vote
accepted
up vote
0
down vote
accepted
If null values are not handled and that it is designed such that there would never be any value that belongs to multiple classes, then you could do this:
public class DynamicHandler {
Map<Class, StaticHandler> handlers;
public <T> void handle(T value) {
if(value != null) {
handlers.entrySet()
.stream()
.filter(entry ->
entry.getKey().isInstance(value))
.findAny()
.ifPresent(entry ->
entry.getValue().handle(value));
}
}
public void <T> register(StaticHandler<T> handler) {
handlers.put(handler.getHandlingClass(), handler);
}
}
interface StaticHandler<T>
{
void handle(T value);
Class<T> getHandlingClass();
}
public class StringHandler implements StaticHandler<String> {
@Override public void handle(String value) {
...
}
@Override public final Class<String> getHandlingClass() {
return String.class;
}
}
If null values are not handled and that it is designed such that there would never be any value that belongs to multiple classes, then you could do this:
public class DynamicHandler {
Map<Class, StaticHandler> handlers;
public <T> void handle(T value) {
if(value != null) {
handlers.entrySet()
.stream()
.filter(entry ->
entry.getKey().isInstance(value))
.findAny()
.ifPresent(entry ->
entry.getValue().handle(value));
}
}
public void <T> register(StaticHandler<T> handler) {
handlers.put(handler.getHandlingClass(), handler);
}
}
interface StaticHandler<T>
{
void handle(T value);
Class<T> getHandlingClass();
}
public class StringHandler implements StaticHandler<String> {
@Override public void handle(String value) {
...
}
@Override public final Class<String> getHandlingClass() {
return String.class;
}
}
answered Nov 8 at 9:54
Jai
5,17311131
5,17311131
@Jal I am currently planning on ignoring null values, it seems to make little sense to 'encode' nothing for my intended use case. I think the code you provided is an elegant solution to my problem. I certainly missed the getHandlingClass() idea for the static handler, thanks!
– Matt Mead
Nov 8 at 10:18
@MattMead When it comes to designing API, there are definitely a lot of things to consider. Each approach has its own pros and cons. It's better to be aware of different approaches and then consider from there.
– Jai
Nov 9 at 1:43
add a comment |
@Jal I am currently planning on ignoring null values, it seems to make little sense to 'encode' nothing for my intended use case. I think the code you provided is an elegant solution to my problem. I certainly missed the getHandlingClass() idea for the static handler, thanks!
– Matt Mead
Nov 8 at 10:18
@MattMead When it comes to designing API, there are definitely a lot of things to consider. Each approach has its own pros and cons. It's better to be aware of different approaches and then consider from there.
– Jai
Nov 9 at 1:43
@Jal I am currently planning on ignoring null values, it seems to make little sense to 'encode' nothing for my intended use case. I think the code you provided is an elegant solution to my problem. I certainly missed the getHandlingClass() idea for the static handler, thanks!
– Matt Mead
Nov 8 at 10:18
@Jal I am currently planning on ignoring null values, it seems to make little sense to 'encode' nothing for my intended use case. I think the code you provided is an elegant solution to my problem. I certainly missed the getHandlingClass() idea for the static handler, thanks!
– Matt Mead
Nov 8 at 10:18
@MattMead When it comes to designing API, there are definitely a lot of things to consider. Each approach has its own pros and cons. It's better to be aware of different approaches and then consider from there.
– Jai
Nov 9 at 1:43
@MattMead When it comes to designing API, there are definitely a lot of things to consider. Each approach has its own pros and cons. It's better to be aware of different approaches and then consider from there.
– Jai
Nov 9 at 1:43
add a comment |
up vote
0
down vote
- In the DynamicHandler class, how can I get the type of T without having an instance of T?
The common solution for this is to pass it a Class object:
void <T> register(StaticHandler<T> handler, Class<T> clazz)
{
handlers.put(clazz, handler);
}
Just as one example of this in a commonly used library: Gson does something similar to register JSON serializers for specific types with GsonBuilder.registerTypeHierarchyAdapter
Or with the same idea, add a method in StaticHandler that gives the class of T
– Sodala
Nov 8 at 9:34
@ohlec Thanks, I did wonder about this myself but was unsure if it was the best or most common way to go about it. It seemed a bit redundant for the client to explicitly specify the type as a parameter when it is implicit from T. I will look into doing it this way.
– Matt Mead
Nov 8 at 9:35
@Sodala I also wondered about this approach. I will try both and see which seems to fit better.
– Matt Mead
Nov 8 at 9:37
@MattMead it certainly looks redundant, but due to type erasure clients do need to explicitly provide the type in some way (weather in register or in another method does not really matter)
– ohlec
Nov 8 at 9:40
@Ohlec I see, thanks for the insight.
– Matt Mead
Nov 8 at 9:47
|
show 2 more comments
up vote
0
down vote
- In the DynamicHandler class, how can I get the type of T without having an instance of T?
The common solution for this is to pass it a Class object:
void <T> register(StaticHandler<T> handler, Class<T> clazz)
{
handlers.put(clazz, handler);
}
Just as one example of this in a commonly used library: Gson does something similar to register JSON serializers for specific types with GsonBuilder.registerTypeHierarchyAdapter
Or with the same idea, add a method in StaticHandler that gives the class of T
– Sodala
Nov 8 at 9:34
@ohlec Thanks, I did wonder about this myself but was unsure if it was the best or most common way to go about it. It seemed a bit redundant for the client to explicitly specify the type as a parameter when it is implicit from T. I will look into doing it this way.
– Matt Mead
Nov 8 at 9:35
@Sodala I also wondered about this approach. I will try both and see which seems to fit better.
– Matt Mead
Nov 8 at 9:37
@MattMead it certainly looks redundant, but due to type erasure clients do need to explicitly provide the type in some way (weather in register or in another method does not really matter)
– ohlec
Nov 8 at 9:40
@Ohlec I see, thanks for the insight.
– Matt Mead
Nov 8 at 9:47
|
show 2 more comments
up vote
0
down vote
up vote
0
down vote
- In the DynamicHandler class, how can I get the type of T without having an instance of T?
The common solution for this is to pass it a Class object:
void <T> register(StaticHandler<T> handler, Class<T> clazz)
{
handlers.put(clazz, handler);
}
Just as one example of this in a commonly used library: Gson does something similar to register JSON serializers for specific types with GsonBuilder.registerTypeHierarchyAdapter
- In the DynamicHandler class, how can I get the type of T without having an instance of T?
The common solution for this is to pass it a Class object:
void <T> register(StaticHandler<T> handler, Class<T> clazz)
{
handlers.put(clazz, handler);
}
Just as one example of this in a commonly used library: Gson does something similar to register JSON serializers for specific types with GsonBuilder.registerTypeHierarchyAdapter
edited Nov 8 at 9:51
answered Nov 8 at 9:29
ohlec
1,560717
1,560717
Or with the same idea, add a method in StaticHandler that gives the class of T
– Sodala
Nov 8 at 9:34
@ohlec Thanks, I did wonder about this myself but was unsure if it was the best or most common way to go about it. It seemed a bit redundant for the client to explicitly specify the type as a parameter when it is implicit from T. I will look into doing it this way.
– Matt Mead
Nov 8 at 9:35
@Sodala I also wondered about this approach. I will try both and see which seems to fit better.
– Matt Mead
Nov 8 at 9:37
@MattMead it certainly looks redundant, but due to type erasure clients do need to explicitly provide the type in some way (weather in register or in another method does not really matter)
– ohlec
Nov 8 at 9:40
@Ohlec I see, thanks for the insight.
– Matt Mead
Nov 8 at 9:47
|
show 2 more comments
Or with the same idea, add a method in StaticHandler that gives the class of T
– Sodala
Nov 8 at 9:34
@ohlec Thanks, I did wonder about this myself but was unsure if it was the best or most common way to go about it. It seemed a bit redundant for the client to explicitly specify the type as a parameter when it is implicit from T. I will look into doing it this way.
– Matt Mead
Nov 8 at 9:35
@Sodala I also wondered about this approach. I will try both and see which seems to fit better.
– Matt Mead
Nov 8 at 9:37
@MattMead it certainly looks redundant, but due to type erasure clients do need to explicitly provide the type in some way (weather in register or in another method does not really matter)
– ohlec
Nov 8 at 9:40
@Ohlec I see, thanks for the insight.
– Matt Mead
Nov 8 at 9:47
Or with the same idea, add a method in StaticHandler that gives the class of T
– Sodala
Nov 8 at 9:34
Or with the same idea, add a method in StaticHandler that gives the class of T
– Sodala
Nov 8 at 9:34
@ohlec Thanks, I did wonder about this myself but was unsure if it was the best or most common way to go about it. It seemed a bit redundant for the client to explicitly specify the type as a parameter when it is implicit from T. I will look into doing it this way.
– Matt Mead
Nov 8 at 9:35
@ohlec Thanks, I did wonder about this myself but was unsure if it was the best or most common way to go about it. It seemed a bit redundant for the client to explicitly specify the type as a parameter when it is implicit from T. I will look into doing it this way.
– Matt Mead
Nov 8 at 9:35
@Sodala I also wondered about this approach. I will try both and see which seems to fit better.
– Matt Mead
Nov 8 at 9:37
@Sodala I also wondered about this approach. I will try both and see which seems to fit better.
– Matt Mead
Nov 8 at 9:37
@MattMead it certainly looks redundant, but due to type erasure clients do need to explicitly provide the type in some way (weather in register or in another method does not really matter)
– ohlec
Nov 8 at 9:40
@MattMead it certainly looks redundant, but due to type erasure clients do need to explicitly provide the type in some way (weather in register or in another method does not really matter)
– ohlec
Nov 8 at 9:40
@Ohlec I see, thanks for the insight.
– Matt Mead
Nov 8 at 9:47
@Ohlec I see, thanks for the insight.
– Matt Mead
Nov 8 at 9:47
|
show 2 more comments
Matt Mead is a new contributor. Be nice, and check out our Code of Conduct.
Matt Mead is a new contributor. Be nice, and check out our Code of Conduct.
Matt Mead is a new contributor. Be nice, and check out our Code of Conduct.
Matt Mead is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53204762%2fjava-dynamic-type-contraints%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Could you try to state your second question more clearly? I struggle to figure out what exactly you're asking here.
– ohlec
Nov 8 at 9:30
You can call
getClass()on the object passed in inDynamicHandler.handle()instead of usingobj.classwhich wouldn't compile. You presume ifnullis passed in, there should be nothing that you would need to handle, and there won't be any chance that an object matches with multiple keys from the map.– Jai
Nov 8 at 9:38
@Jal My apologies, that was actually just a mistake in my code. I updated it to used getClass() instead. I also clarified my first question to make it clear I want to know how to get the type of T in the register method.
– Matt Mead
Nov 8 at 9:45
@Ohlec I have edited my second question, hopefully it is clearer now.
– Matt Mead
Nov 8 at 9:45
@MattMead how do you imagine a client using this as a map? Isn't
handle()already the most convenient interface for this?– ohlec
Nov 8 at 9:56