I've created a class which holds a bunch of properties values.
In order to initialize that class, I have to call some static method "configure()" which configures it from an XML file.
That class was supposed to act to store some data such that I could just write
PropClass.GetMyProperty();
I call the configure() from a static block in the main so I can use it anywhere
BUT
If I set a static constant member of some other class to a value from my "PropClass", I get null,
class SomeClass {
static int myProp = PropClass.GetMyProperty();
}
That's probably because that expression is evaluated before the call to configure.
How can I solve this issue?
How can I enforce that the call to configure() will be executed first?
Thanks
you could use a static code block to do that
static {
configure();
}
the syntax of a static initializer block? All that is left is the keyword static and a pair of matching curly braces containing the code that is to be executed when the class is loaded. taken from here
I would do the following:
class SomeClass
{
// assumes myProp is assigned once, otherwise don't make it final
private final static int myProp;
static
{
// this is better if you ever need to deal with exceeption handling,
// you cannot put try/catch around a field declaration
myProp = PropClass.GetMyProperty();
}
}
then in PropClass do the same thing:
class PropClass
{
// again final if the field is assigned only once.
private static final int prop;
// this is the code that was inside configure.
static
{
myProp = 42;
}
public static int getMyProperty();
}
Also. if possible, don't make everything static - at the very least use a singleton.
Can you not make the GetMyProperty() method check whether configure() has been called already ? That way you can call GetMyProperty() without having to worry about wheher our object is configured. Your object will look after this for you.
e.g.
public String getMyProperty() {
if (!configured) {
configure();
}
// normal GetMyProperty() behaviour follows
}
(you should synchronise the above if you want to be thread-safe)
Dude, sounds like you should be using Spring Framework (or some other Dependency Injection framework). In Spring, you already get everything that you need:
An XML format for defining beans with configurable properties, no need to code the logic for reading the XML and initializing the beans yourself.
Beans are initialized when you need them (provided that you access them in the correct manner). The best way would be to inject the beans into the callers.
Don't invent the wheel... Spring is one of the most commonly used frameworks in Java. IMHO, no large Java application should be coded without it.
Related
Consider and example as below:
public class LoggerTestClass {
private static final Logger LOGGER = Logger.getLogger(LoggerTestClass.class);
}
In above example parameter passed to getLogger method is hard coded i.e LoggerTestClass.class
Now every time I change the class name I have to change the getLogger method's parameter.
Any other way which will fetch the class name automatically, for example for non static variable we can add this.getClass()
You can use Lombok to achive it in a clean fashion. All you need to do is to put #Log on top of your class and it will give you a log object to work with.
Read more here
Bro,For the question,first of all,we need make clear some concept.
In java,if a identifier is a member of a class,and decorated by 'static' keyword,it's value is Decided in the compile phase.
If the 'final' keyword is added,the identifier is constant,it's value must have a initial value on it is declared.and the value can't be change in the java runtime.
And the interesting thing is, the static constent is only declared inside the class,it can be called 'Classname' + '.' ,but has no connection to the class context.if there's no context ,the identifier con't become dynamic.
I think if let the identifier become dynamic ,there are only two ways:
let the identifier become a variable.remove the 'final' key word.the code look like this:
class Test {
private static Logger LOGGER;
public Test() {
LOGGER = Logger.getLogger(getClass().getSimpleName());
}
}
The 'private' keyword is sufficient if you don't want other classes to access it.
Try the java dynamic proxy. it can change the class in java runtime.
Code happy ~
Welcome to talk with me~
Can you use java 9+? Then solution is pretty simple:
private static final Logger LOGGER = Logger.getLogger(MethodHandles.lookup().lookupClass());
As MethodHandles.lookup() creates lookup using caller class. (via Reflection.getCallerClass() but Reflection is internal API, so you need that additional method handle lookup step)
I am using Java CDI for bean lifecycle.
#Named
public class ManagedBeanClass{
...
public ManagedProfile getManagedProfile(){
return new ManagedProfile();//logic will goes here
}
}
For Example
public class sample1{
#Inject private ManagedBeanClass managedBeanClass;
...
public static boolean methodExample() throws Exception{
ManagedProfile managedProfile = managedBeanClass.getManagedProfile();
....
}
}
Try to Inject(#Inject) Managed bean into Static method ,it shows compaliaton error
Cannot make a static reference to the non-static field
managedBeanClass
Getting stuck with Context DI and Static Object lifecycle.
Help me resolve this thanks in advance.
The problem in your example code has nothing to do with CDI; You are trying to access a non-static field (managedBeanClass) from a static method. This is not possible in Java (neither with nor without CDI).
Also, static methods almost always point to a design problem (*). Having static methods like that make your program harder to test and harder to change / maintain. Try to come up with a design that does not need static methods at all...
So, the short answer is: Don't.
But if your really must have a static method here, you can use constructor injection and set a static field from the constructor. But beware: This is potentially dangerous, because every new instance would set the field again (which could cause race conditions and unexpected behaviour).
(See also: https://stackoverflow.com/a/22068572/10363398)
(*) With a few exceptions, like the methods in the Math class. But those are very small, pure functions that have no side-effects.
My question is the same as this one except it is for Java, specifically applied to properties. Ideally I would like to create one instance of Properties, and call the methods from all of the classes without creating new instances. I would also want to read from a single instance of properties so I only have a single source of the truth.
I have read the API for Properties and it doesn't answer my question.
This question indicates I need to include the reference in the class constructor. Is there a better way??
The fisrt link, "this one" is a link to the Oracle documentation...
If you want to load your properties only once, you should use the singleton pattern. But be carefull that this pattern can be an anti-pattern and may make your unit tests more complex.
To avoid those drawbacks it is better to pass the reference to your properties via a constructor.
/* This is your singleton. It takes care of loading the properties only once and can delegate access method to it */
public class Configuration {
private static Configuration instance; // created only once
public static getInstance() {
instance = // Read the Singelton pattern to create it only once
}
private Properties properties; // loaded only once
public String get(String key) {
return properties.getProperty(key);
}
}
public class Component {
private final Configuration cfg;
public Component (Configuration cfg) {
this.cfg = cfg;
}
}
public class StarterOrDiContainer {
// ..
Component component = new Component(cfg.getInstance());
}
Let's take the system properties as example. In this implementation http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/System.java#System.getProperty%28java.lang.String%29, the properties are just stored in a static class attribute. Either make this attribute public or create public accessor methods. Short answer: just make it static.
You can initialize static data with static initializers, if things get a little bit more complex. (https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html)
I have a bunch of constants throughout my code for various adjustable properties of my system. I'm moving all of them to a central .properties file. My current solution is to have a single Properties.java which statically loads the .properties file and exposes various getter methods like this:
public class Properties {
private static final String FILE_NAME = "myfile.properties";
private static final java.util.Properties props;
static {
InputStream in = Properties.class.getClassLoader().getResourceAsStream(
FILE_NAME);
props = new java.util.Properties();
try {
props.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String getString(Class<?> cls, String key) {
return props.getProperty(cls.getName() + '.' + key);
}
public static int getInteger(Class<?> cls, String key) {
return Integer.parseInt(getString(cls, key));
}
public static double getDouble(Class<?> cls, String key) {
return Double.parseDouble(getString(cls, key));
}
}
The only problem with that is that for every constant that I get from this file, I have some boilerplate:
private final static int MY_CONSTANT = Properties.getInteger(
ThisClass.class, "MY_CONSTANT");
I don't think I want to use Spring or the like as that seems like even more boilerplae. I was hoping to use a custom annotation to solve the issue. I found this tutorial, but I can't really sort out how to get the functionality that I want out of the annotation processing. The Java docs were even less helpful. This should be a thing I should be able to do at compile time, though. I know the names of the class and field.
What I'm thinking is something like this:
#MyAnnotation
private static final int MY_CONSTANT;
Anyone know how I would go about doing this or at least best practices for what I want to do?
First of all, you shouldn't do it. It's practical, but too hacky and if you ever want to write a test using different settings, you'll run into problems. Moreover, nobody's gonna understand how it works.
An annotation processor can probably do nothing for you. A Lombok-style-hacking processor can. You want to make
#MyAnnotation
private static final int MY_CONSTANT;
work like
private final static int MY_CONSTANT =
Properties.getInteger(ThisClass.class, "MY_CONSTANT");
The original expression doesn't compile (due to the uninitialized final variable), but it parses fine and Lombok can do its job. There's already something related there:
#Value changes the modifiers to final private
#UtilityClass makes all fields static
So actually, you could write just
#MyAnnotation
int MY_CONSTANT;
and let your annotation change also the modifiers. I'd look at the eclipse and javac handlers for #UtilityClass, I guess all you need is to generate the initializer (which is quite some work because it's all damn complicated).
I don't think Lombok itself will implement this anytime soon, since
all the static stuff is non-testable and mostly bad style
and not everyone wants this in their code
it's not that much boilerplate
it also magically refers to the class Properties, but this could be solved via configuration
but I guess a contribution might be accepted.
Actually not quite clear why and what do you want to archive.
As I correctly undestand, you want use special kind of annotations to automatically assign values for static final constants from some properties file. Unfortunatelly it is impossible without special hacks. And annotations have nothing to do with this.
The reason is that final fields must be initialized and it is compiler's request. There aren't special annotations in java which will provide such syntactic sugar which you want.
But if you insist on this there are two ways:
Extrim way. Init all properties field with default value. Then using this hack in some static init section initialize this value using reflection mechanism and you code via reading values from properties.
Less extrim way: refuse request of final modifiers for properties fields, and using only reflection fill these fields values.
And additionally, for these ways, yes you can use annotations. But you will have to solve following technical issues:
1) Find all fields in all classes in classpath, which are annotated with you special annotation. Look at:
Get all of the Classes in the Classpath and Get list of fields with annotation, by using reflection
2) Force your Properties class to be initialized in all possible enter points of your application. In static section in this class you will load your properties file, and then using (1) method with reflection and classloader, assign values to all constants.
My project is heavily using dependency injection, and I'm being very careful to avoid service locator antipattern. All objects are structured using constructor injection that allow easily identifiable list of dependencies. Now I'm building an object, and it has a special "constant" instance, which is basically static/singleton (consider example of something like Integer.MinValue). So my initial reflex was to create a static field with a static "getter" method, which would create the instance of the object if it wasn't previously created. The object itself has dependencies however, so I'm confused on what's the best practice for instantiating this "special instance". I'm looking for recommendations on how to best structure code in this scenario, ideally without having to call upon the container for resolution of dependencies. Some code:
public class PressureUnit extends DataUnit {
private static PressureUnit standardAtmosphere;
public static PressureUnit StandardAtmosphere() {
if(standardAtmosphere == null){
standardAtmosphere = new PressureUnit(1013.25); // this line is what is bothering me as I need to resolve other dependencies (have to use new as it's a static method and can't be injected like everywhere else)
}
return standardAtmosphere;
}
#AssistedInject
public PressureUnit(ITimeProvider timeProvider, IUnitProvider unitProvider, #Assisted double value) {
this(timeProvider, unitProvider, value, PressureUnits.hPa);
}
...
}
I really don't see any problem in your code since you are not newing up dependencies here and there, now with that being said i can give some suggestions:
If you specifically want the container to call an existing static factory method, you can use StaticFactoryExtension.
Why don't you use a factory.
Consider refactoring you design and removing the static method if possible.