{"id":55,"date":"2007-12-22T16:52:46","date_gmt":"2007-12-22T15:52:46","guid":{"rendered":"http:\/\/www.gamlor.info\/wordpress\/?p=55"},"modified":"2021-03-11T09:43:20","modified_gmt":"2021-03-11T08:43:20","slug":"runtime-generics","status":"publish","type":"post","link":"https:\/\/www.gamlor.info\/wordpress\/2007\/12\/runtime-generics\/","title":{"rendered":"Runtime-Generics"},"content":{"rendered":"<p>I&#8217;m a heavy user of generalized classes and interfaces in Java.Sadly, the generalization is only for compile-time checks. But because you can cast any parameterized class-instance to an unchecked instance you can fool the system. This can be very annoying if a class-cast exception occurs later. For example with collections, the ClassCastException happens somewhere later and the stacktrace points to the wrong location.<\/p>\n<p>Well for Collections there is a simple solution available. You can create runtime-checked Collections with the Collections-class<\/p>\n<p><em>&#160;&#160;&#160; List&lt;String&gt; test = Collections.checkedList(new ArrayList&lt;String&gt;(),String.class);      <br \/>&#160;&#160;&#160; List somewhereElse = test;       <br \/>&#160;&#160;&#160; somewhereElse.add(44); \/\/ Here the ClassCastException will be thrown<\/em><\/p>\n<p>The bad thing is, this is made just for collections. Now I&#8217;m thinking about creating an small library, which can create runtime-checks for any interface. Since I saw the little trick on the Google-Guice-library, this seems to be solvable. Sure, you have to use some dirty tricks to archive this goal, but maybe it is realizable.<\/p>\n<p>The following code-snippet shows, what I&#8217;m thinking of:<\/p>\n<p><em>&#160;&#160;&#160; \/\/ This is our target-type      <br \/>&#160;&#160;&#160; Task&lt;Map&lt;String, ?&gt;, List&lt;? extends InputStream&gt;&gt; targetType; <\/em><\/p>\n<\/p>\n<p><em>&#160;&#160;&#160; \/\/ To create in the code, we create an inner-class of the Type-interface.      <br \/>&#160;&#160;&#160; \/\/&#160; This type will be interpreted by the system to create the typed version.       <br \/>&#160;&#160;&#160; \/\/&#160; Then we bind it the the normal implementation class and create an instance at the end.       <br \/>&#160;&#160;&#160; targetType =       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RuntimeTypeSave.create(new Type&lt;Task&lt;Map&lt;String, ?&gt;, List&lt;? extends InputStream&gt;&gt;&gt;() {})       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .bindTo(new HashMap())       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .createInstance(); <\/em><\/p>\n<p><em><\/em><\/p>\n<p><em><\/em><\/p>\n<\/p>\n<p>And the code for more dynamic creation, for example when you create a typed based on configuration:<\/p>\n<p><em>&#160;&#160;&#160; \/\/ There has to be a possibility to create the same type complete dynamically.      <br \/>&#160;&#160;&#160; \/\/&#160; Because the type may get constructet depending on a configuration. <\/em><\/p>\n<\/p>\n<p><em>&#160;&#160;&#160; \/\/ Build the first parameter The Type.ANY_TYPE represents the ? on the parameterlist.      <br \/>&#160;&#160;&#160; Builder&lt;Map&gt; firstParam = RuntimeTypeSave.getBuilder(Map.class);       <br \/>&#160;&#160;&#160; Type firstType = firstParam.setParameters(String.class, Type.ANY_TYPE.class).createType(); <\/em><\/p>\n<p><em>&#160;&#160;&#160; \/\/ Create the second parameter      <br \/>&#160;&#160;&#160; Builder&lt;List&gt; secondParam = RuntimeTypeSave.getBuilder(List.class);       <br \/>&#160;&#160;&#160; Type secondType = secondParam.extendsFrom(InputStream.class).createType(); <\/em><\/p>\n<p><em>&#160;&#160;&#160; \/\/ Create the final type      <br \/>&#160;&#160;&#160; Type&lt;Task&gt; finalType = RuntimeTypeSave       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; .getBuilder(Task.class).setParameters(firstType, secondType)       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; .createType(); <\/em><\/p>\n<p><em>&#160;&#160;&#160; \/\/ Ugly cast =(      <br \/>&#160;&#160;&#160; targetType = (Task&lt;Map&lt;String,?&gt;, List&lt;? extends InputStream&gt;&gt;) RuntimeTypeSave.create(finalType).       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; bindTo(new TaskImpl()).createInstance();<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m a heavy user of generalized classes and interfaces in Java.Sadly, the generalization is only for compile-time checks. But because you can cast any parameterized class-instance to an unchecked instance&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[15],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/55"}],"collection":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/comments?post=55"}],"version-history":[{"count":1,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/55\/revisions"}],"predecessor-version":[{"id":3768,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/55\/revisions\/3768"}],"wp:attachment":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/media?parent=55"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/categories?post=55"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/tags?post=55"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}