I had a static class that contained several static variables:
public class A{
static {
}
public static final String param1= "paramVal1";
public static final String param2= "paramVal2";
}
I want to change the code, so that the variables will be in a map:
public class A{
static {
}
private static Map<String, String> params = new HashMap<String, String>() ;
public static void initParams() {
params.put("param1", paramVal1);
params.put("param2", paramVal2);
}
However, I already have many classes that call those public parameters, and I don't want to go to every class and change it. Is there any way to use some define function, that would cause java to return the map's value, when the parameter is called? i.e if someone calls A.param1, it would return params.get("param1")
A parameter in not as easy to use (and overwrite) than a method. So I think that short answer to your question is no. That's one of the reasons of getters and setters. But you can allways do the inverse, that is keep the old parameters for compatibility and use a map for newer uses :
public class A{
static {
param1 = "paramVal1";
param2 = "paramVal2";
params = new HashMap<String, String>;
params.put("param1", param1);
params.put("param2", param2);
// eventually other inits for params
}
public static final String param1= "paramVal1";
public static final String param2= "paramVal2";
public static Map<String, String params;
/* or better private static Map<String,String> params
and access via getter */
public static getParam(String name) {
return param.get(name);
}
}
That way, old classes could allways do A.param1, and for newer classes you could start using A.get("param1").
You can do this:
public class A {
private static Map<String, String> params = new HashMap<String, String>();
static {
params.put("param1", "paramVal1");
params.put("param2", "paramVal2");
}
public static final String param1 = params.get("param1");
public static final String param2 = params.get("param2");
}
Related
I have the below code :
public final class SomeStaticClass {
private static Map<String, Map<String,String>> tMap;
private SomeStaticClass(){
//Private Constructor to avoid instance creation
}
//getter method here to retrieve the map.
public static void setMap(Map<String, Map<String,String>> map){
tMap = map;
}
}
I want to restrict the setMap method to be called only once,so that the tMap cannot be modified later.
The tMap will be set only once during application startup and will be access by multiple objects later.
public static void setMap(Map<String, Map<String,String>> map){
if (null == tMap) // This will make sure tMap initialized only once
tMap = map;
}
I have a class with static variable
#Data
public final class Code {
private static Map<String, List<String>> codesForType = new HashMap<String, List<String>>() {{
put("code1", Arrays.asList("AVDF", "WREQ", "AWER"));
put("code2", Arrays.asList("SHYT", "DWEA", "XSSS", "AQWE"));
}};
public static List<String> getCodesByType(String type) {
return codesForType.get(type);
}
}
with following api
#GetMapping("/codes")
public Code getCodeForType() {
return new Code();
}
This is giving exception with message No converter found for return value of type: class com.model.Code.
Tried making the member as public but still has the same issue.
It works when I remove static keyword from private static Map<String, List<String>> codesForType
I could be missing a basic understanding of static keyword.
You don't need to create a new object as your methods are static.
you can simply do this :
#GetMapping("/codes")
public List<String> getCodeForType() {
// replace type with something you will receive in your request.
return Code.getCodesByType(type);
}
I have a problem with Java static initialization. What I want to do is some type checking with generic constants and to translate between types and type names. So I have some typed constants in interface MC and a hash map in inner class Type to translate names to types. Now when I call MC.Type.getValue("MInteger") the inner class Type is initialized but not the static constants in the outer class MC so the return value is null. How can I get Java to initialize these constants? I could do
static { Type<?> dummy = MC.MBoolean; }
in class Type but isn't there some better way to do this. Or am I doing this totally wrong.
import java.util.HashMap;
import java.util.Map;
interface MC {
public static final Type<Boolean> MBoolean = new Type<>("MBoolean");
public static final Type<Integer> MInteger = new Type<>("MInteger");
public static class Type<T> {
private static final Map<String, Type<?>> types = new HashMap<>();
private final String name;
private Type(String name) {
this.name = name;
types.put(name, this);
}
public String getName() {
return name;
}
public static Type<?> getValue(String name) {
return types.get(name);
}
}
}
public class Main {
public static void main(String[] args) {
System.out.println(MC.Type.getValue("MInteger"));
MC.MBoolean.getName();
System.out.println(MC.Type.getValue("MInteger"));
}
}
Since all Type instances are included in your MC class, a very direct approach to solving this problem would be to move registration of the class with the Type.types map from the constructor of Type to its static initializer:
private static final Map<String, Type<?>> types = new HashMap<>();
static {
types.put(MBoolean.getName(), MBoolean);
types.put(MInteger.getName(), MInteger);
}
private Type(String name) {
this.name = name;
// removed types.put(name, this); from here
}
Demo.
You can use either static initializer block:
private static final Map<String, Type<?>> types = new HashMap<>();
static {
types.put(MC.MBoolean.getName(), MC.MBoolean);
types.put(MC.MInteger.getName(), MC.MInteger);
}
or double brace initialization:
private static final Map<String, Type<?>> types = new HashMap<>() {{
put(MC.MBoolean.getName(), MC.MBoolean);
put(MC.MInteger.getName(), MC.MInteger);
}};
First curly braces creates new anonymous subclass of HashMap, second curly braces are instance initializer block which is executed at construction time (arg-less constructor for anonymous classes).
The Constructor won't initialize unless you explicitly call MC.MBoolean. so better you go with the Double brace initialization.
private static final Map<String, Type<?>> types = new HashMap<>() {
{
put(MC.MBoolean.getName(), MC.MBoolean);
put(MC.MInteger.getName(), MC.MInteger);
}
};
I have a class
like below
public class SampleReflection {
public static final String TWO_name = "html";
public static final String TWO_find = "css";
public static final String ONE_KEY_java = "java";
public static final String ONE_KEY_jsp = "jsp";
public static final String ONE_KEY_oracle = "oracle";
public static final String ONE_KEY_spring = "spring";
public static final String ONE_KEY_struts = "struts";
}
I would like to get all the fields which starts with ONE_KEY and their value.
because the ONE_KEY_xxx can be of any numbers.
how to do this in java reflection or any other way in java ?
thanks
You can use SampleReflection.class.getDeclaredFields(), iterate over the result and filter by name. Then call field.get(null) to get the value of the static fields. If you want to access non-public fields as well you might have to call first.setAccessible(true) (provided the security manager allows that).
Alternatively you could have a look at Apache Common's reflection utilities, e.g. FieldUtils and the like.
Depending on what you actually want to achieve there might be better approaches though, e.g. using a map, enums etc.
In your case where you have static fields using an enum might be a better way to go.
Example:
enum SampleFields {
TWO_name("html"),
TWO_find("css"),
ONE_KEY_java("java"),
ONE_KEY_jsp("jsp");
ONE_KEY_oracle("oracle"),
...;
private String value;
private SampleFields(String v) {
value = v;
}
}
Then iterate over SampleFields.values() and filter by name.
Alternatively, if that fits your needs, you could split the names and pass a map to the enum values, e.g.
enum SampleFields {
TWO(/*build a map "name"->"html","find"->"css")*/ ),
ONE_KEY(/*build a map "java"->"java","jsp"->"jsp", ...*/);
private Map<String, String> values;
private SampleFields(Map<String, String> map) {
values = map;
}
}
Then get the enum values like this: SampleFields.valueOf("ONE_KEY").get("java")
Thanks for the answer,
this is what i was looking for,
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class SampleReflection {
public static final String TWO_name = "html";
public static final String TWO_find = "css";
public static final String ONE_KEY_java = "java";
public static final String ONE_KEY_jsp = "jsp";
public static final String ONE_KEY_oracle = "oracle";
public static final String ONE_KEY_spring = "spring";
public static final String ONE_KEY_struts = "struts";
public static void main(String[] args) {
Class<?> thisClass = null;
Map<String,String> keyValueMap = new HashMap<String,String>();
try {
thisClass = Class.forName(SampleReflection.class.getName());
Field[] aClassFields = thisClass.getDeclaredFields();
for(Field f : aClassFields){
String fName = f.getName();
if(fName.contains("ONE_KEY")){
keyValueMap.put(fName, (String)f.get(SampleReflection.class));
}
}
for (Map.Entry<String, String> entry : keyValueMap.entrySet())
{
System.out.println(entry.getKey() + "=" + entry.getValue());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Is there a Java standalone implementation to extract values of parameters in an URI as defined by an URI-Template (RFC 6570)?
The best implementation I've found is a ruby implementation ( https://github.com/sporkmonger/addressable )
Via http://code.google.com/p/uri-templates/wiki/Implementations I found a Java implementation: Handy-URI-Templates
It supports the resolution of an URI-Template with parameter values to a final URI. Unfortunately, it can not do the reverse: extraction of parameter values in the URI according URI-Template.
Implentations of the JAX-RS (or Restlet) have this feature internally.
But none seems to have isolated this feature module which could used independently.
Does anyone have another idea?
Here a example to Use spring-Web :
import org.springframework.web.util.UriTemplate;
public class UriParserSpringImpl implements UriParser {
private final UriTemplate uriTemplate;
private final String uriTemplateStr;
public UriParserSpringImpl(final String template) {
this.uriTemplateStr = template;
this.uriTemplate = new UriTemplate(template);
}
#Override
public Map<String, String> parse(final String uri) {
final boolean match = this.uriTemplate.matches(uri);
if (!match) {
return null;
}
return uriUtils.decodeParams(this.uriTemplate.match(uri));
}
#Override
public Set<String> getVariables() {
return Collections.unmodifiableSet(new LinkedHashSet<String>(this.uriTemplate.getVariableNames()));
}
}
Another for Jersey (JAX-RS implementation) :
import com.sun.jersey.api.uri.UriTemplate;
public class UriParserJerseyImpl implements UriParser {
private final UriTemplate uriTemplate;
private final Map<String, String> valuesMaps;
public UriParserJerseyImpl(final String template) {
this.uriTemplate = new UriTemplate(template);
final Map<String, String> valuesMaps = new HashMap<String, String>();
for (final String prop : this.uriTemplate.getTemplateVariables()) {
valuesMaps.put(prop, null);
}
this.valuesMaps = Collections.unmodifiableMap(valuesMaps);
}
#Override
public Map<String, String> parse(final String uri) {
final Map<String, String> values = new HashMap<String, String>(this.valuesMaps);
final boolean match = this.uriTemplate.match(uri, values);
if (!match) {
return null;
}
return values;
}
#Override
public Set<String> getVariables() {
return this.valuesMaps.keySet();
}
}
With interface :
public interface UriParser {
public Set<String> getVariables();
public Map<String, String> parse(final String uri);
}
The damnhandy uri template library has an open issue for exactly this feature. I've already gotten the PR for the feature merged and it should be out in version 2.2! Head over there and let the maintainers know you're interested.
Also if you can't wait, you can see how I did it here and use that for yourself.
java.net.URI
Can't set the parameters after it's instantiated, but it has a nice set of getters and you can contruct a new one to alter it.