I'm very to Java and I use enum for the first time like this:
public class Web {
public String baseUrl;
public static enum Environment {
DEVELOPMENT("http://development") ,
PRODUCTION("http://production"),
SANDBOX("http://sandbox");
public final String baseUrl;
private Environment(String baseUrl)
{
this.baseUrl = baseUrl;
}
}
}
The enum Environment has the three constants DEVELOPMENT, PRODUCTION,SANDBOX. The Web class also has the baseUrl to which the Environment's baseUrl to be set ( not sure this is the good practice to do so ).
For setting up the baseUrl I'm currently doing like this :
new Web().setBaseUrl(Web.Environment.PRODUCTION.baseUrl)
I'm not sure this is the right way to use the enums with the classes. Are there any way to directly set Web baseUrl to enums baseUrl.
Am I missing something here.
Thanks in advance
I think you're on the right track, but you're losing some of the strength of Java's enum by accessing the URL in this manner. Instead, use the type of the enum to help ensure that you pass correct values to your method. That is, pass the enum alone, and let the method extract whatever value from it. For example:
new Web().setEnvironment(Web.Environment.PRODUCTION);
Now you can only pass Environments to your Web class, rather than any ol' string.
[Edit] Then your Web.setEnvironment method looks like this:
public void setEnvironment(Environment environment) {
this.baseUrl = environment.getBaseUrl();
}
This way, I can't come along and call new Web().setEnvironment("marvo") by accident. It enforces a certain level of correctness.
And vishal_aim is right. Even with Enums you should practice data hiding and encapsulation, so make the instance variable private, and provide an accessor like getBaseUrl() to retrieve the value.
Rather than using directly Enum's member baseUrl you should make it private and have a getter method in enum class. other than that I think it's ok to use enum this way
Make the enum a top level class/enum.
Add a getter for the baseUrl field.
I think there is nothing wrong with how you use Enum. However the code looks little clumsy:
new Web().setBaseUrl(Web.Environment.PRODUCTION.baseUrl)
I would take the Enum out of the Web class and omit the redundant 'baseUrl' field in the Web class- you do not need it since you have the value in your Enum. Instead of the baseUrl I would have a urlType member of type Environment. Also would be nice to add accessor method to the baseUrl inside the Environment enum
Along with what Bohemian and vishal_aim said, you might be unnecessarily exposing the baseUrl member (or getBaseUrl() method after you refactor it in). Instead pass the enum to the Web class and have it dig the URL from the enum. That way, if you keep the enum inside the Web class, you can keep the baseUrl private.
public void setEnvironment(Environment env) {
baseUrl = env.getBaseUrl();
....
}
Related
I am writing a Java program where a method in one class needs to access a method of an object that is a member of another class. I can do this in at least two different ways, passing as a parameter, or directly accessing the object using the name of the class it is a member of. I find a lot of questions about pass-by-reference vs. pass-by-value, but I can't find anything that addresses this scenario.
Here is some pseudo-code showing what I mean:
// class of object to pass
class MyPrefs {
public String getPref(int i){
String s = ... //some code to get a String indexed by i
return s;
}
}
// class where object is instantiated
class Main {
protected static MyPrefs prefs = new MyPrefs();
}
Here are the two options I am looking at. In a third class, Toolbar, I can do either of these:
// pass as parameter
class Toolbar{
public void applyPrefs(MyPrefs p){
String s = p.getPref(1);
...
}
//or use qualified name of object
class Toolbar{
public void applyPrefs(){
String s = Main.prefs.getPref(1);
...
}
}
It works either way, what I would like to know is what are the merits or problems associated with each method, and if there is another way of doing this that I hadn't considered.
I hope this question doesn't get closed for being opinion-based because technically it is. So, I am not going to claim my answer is based on some undisputed best-practice, but I do believe it is generally accepted as the correct approach.
In my opinion, it would be either a variant of the first, and/or a combination of the two. For example:
public static String getProp(String prop) {
// use java.util.Properties to retrieve the property.
}
This works well when your application has a single property file. In cases you have multiple property files, you need to override this method and pass the path to the correct file.
public static String getProp(String filename, String prop) {
// use java.util.Properties to retrieve the property.
}
Where filename could be just the file name or the fully qualified name (with the path). I tend to keep all my property files in the same folder, so I "hard-code" the path and use that as the base location for my files, so most of the time when using this approach, I only need the actual file name.
I also have created utility methods to obtain specific properties where the name of the method implies what property I am obtaining. This is useful for people that are not too familiarized with the property keys.
public static String getXYZProp() {
// use java.util.Properties to load the properties.
return prop.getProperty("XYZ");
}
Alternatively, you should take advantage of the genetic method you created to do the same
public static String getXYZProp() {
return getProp("XYZ");
}
Or even something like
public static String getXYZProp() {
return getProp("someProps.properties", "XYZ");
}
It is OK to have multiple method that ultimately do the same thing. Think that some users will call the generic ones because they are more familiarized with the property keys while others will rely on method with names that help them figure out what properties they need to retrieve.
I'd like to know whats the common style to maintain path constants for Rest Controllers.
For example you have something like that:
#RequestMapping(method = RequestMethod.GET, value = ANY_PATH_VALUE)
I do maintain those constants (in the example ANY_PATH_VALUE) at the moment in a class called PathConstants which looks like this:
public abstract class PathConstants {
public static final String ANY_PATH_VALUE = "/path/{SOME_ID}";
...
}
Is it a common way to keep those values straight at the method of the RestController class or is it like I do currently? Or is there a even more common way how to maintain this kind of stuff?
There are two sides to this,
It actually has close to zero performance problem. This has to something with readability.
The first view is keeping the values as native strings there itself in the controllers. This is more readable in the sense that you can directly check the exact API route when you enter the controller.
The second view is keeping it in some other file with static constants. Keeping all the routes like this actually gives you one common place where you can get to know all the API routes you currently support in your application.
I personally prefer the second i.e. keeping all the paths in a file called APIRoutes and further divided by domains.
public class APIRoutes {
public class SYSTEM {
public static final String HEALTH_CHECK = "api/v1/healthcheck";
public static final String LB_HEALTH_CHECK = "lb/v1/healthcheck";
}
public class API {
public static final String SAVE_X = "api/v1/save";
public static final String GET_X = "api/v1/get";
}
public class CACHE {
public static final String RELOAD_X = "cache/v1/load/x";
public static final String RELOAD_Y = "cache/v1/load/y";
}
}
This way in your controller, you have something like
#RequestMapping(method = RequestMethod.GET, value = APIRoutes.API.SAVE_X)
Using constants seems to be a quite reasonable approach. I would, however, define the constants in a final class with a private constructor throwing an AssertionError to enforce noninstantiability:
public final class PathConstants {
// Suppress default constructor for noninstantiability
private PathConstants() {
throw new AssertionError("No instances for you!");
}
public static final String PATH_TO_FOO = "foo";
public static final String PATH_TO_BAR = "bar";
}
Quoting the Item 4 from Effective Java 3rd edition from Joshua Bloch:
Because the explicit constructor is private, it is inaccessible outside the class. The AssertionError isn’t strictly required, but it provides insurance in case the constructor is accidentally invoked from within the class. It guarantees the class will never be instantiated under any circumstances. This idiom is mildly counterintuitive because the constructor is provided expressly so that it cannot be invoked. It is therefore wise to include a comment, as shown earlier.
As a side effect, this idiom also prevents the class from being subclassed. All constructors must invoke a superclass constructor, explicitly or implicitly, and a subclass would have no accessible superclass constructor to invoke.
You also could use something like #RequestMapping("${foo.bar}"), where foo.bar is a value defined in a property souce (such as an application.properties file or YAML variant).
Quoting the Spring MVC documentation:
URI path patterns can also have embedded ${…} placeholders that are resolved on startup by using PropertyPlaceHolderConfigurer against local, system, environment, and other property sources. You can use this, for example, to parameterize a base URL based on some external configuration.
I think it is a reasonable way to maintain paths. Just make sure you always build the paths from other constants. For example, if your path has version, you define the version as another variable.
public static final String VERSION_1 = "/v1";
public static final String USERS_V1 = VERSION_1 + "/users";
So I am writing a class which I want to follow the best practices and be testable.
I have a new object to be created inside it. So, I am following the factory pattern to achieve it.
public class Apple {
// factory object injected in class
private SeedFactory seedFactory;
// Method to be tested
public void myMethod(String property1, int property2, String depends) {
// Just to set the necessary parameter
seedFactory = new SeedFactory(property1, property2);
// Factory pattern intact. Instance generation depends on only one parameter
SeedFactory result = seedFactory.getInstance(depends);
}
}
EDIT: Adding code for factory as well.
public class SeedFactory{
String property1;
int property2;
SeedFactory(property1,property2){
this.property1 = property1;
this.property2 = property2;
}
SeedFactory getInstance(int depends){
if(depends == 1)
{ // do stuff }
else{ // do stuff and return instance }
Now, before I actually create the new object, I have to make sure that I set two properties for the new instance to be generated, which are needed to be present irrespective of the type of instance generated by the factory. depends is the actual parameter which tells the factory what instance to return.
Now, as far as testability of this code is concerned, I can user PowerMockito to mock the factory object using whenNew but using PowerMockito is not a choice. I have to make it testable without it.
Also, I have tried to encapsulate the new call within a one line function and then use spy. But I want to avoid using spy, since it is not considered a good practice, in context of where this code is being used as a whole.
So my question is, Is there any way, without using PowerMockito, to re-write this class so that it can be unit tested properly?
If the instance to be generated needed only one parameter, then it would have been trivial. However, I don't want to pass more than one parameter to getInstance().
SeedFactory is not Apple's dependancy but your method depends on SeedFactory which has "uses" relationship. So to define proper relation i would suggest you use "USES" relation as below:
public void myMethod(SeedFactory seedFactory, String depends){ // Method to be tested
Now you could mock SeedFactory and can unit test it appropriately.
I think you're doing something wrong.
If SeedFactory isn't an Apple's dependency but an internal concern, hence you don't need to mock a SeedFactory to test Apple. You should test the public API provided by Apple only.
If SeedFactory is an Apple's dependency, so it definitely should be injected.
I have a class that must have some static methods. Inside these static methods I need to call the method getClass() to make the following call:
public static void startMusic() {
URL songPath = getClass().getClassLoader().getResource("background.midi");
}
However Eclipse tells me:
Cannot make a static reference to the non-static method getClass()
from the type Object
What is the appropriate way to fix this compile time error?
The Answer
Just use TheClassName.class instead of getClass().
Declaring Loggers
Since this gets so much attention for a specific usecase--to provide an easy way to insert log declarations--I thought I'd add my thoughts on that. Log frameworks often expect the log to be constrained to a certain context, say a fully-qualified class name. So they are not copy-pastable without modification. Suggestions for paste-safe log declarations are provided in other answers, but they have downsides such as inflating bytecode or adding runtime introspection. I don't recommend these. Copy-paste is an editor concern, so an editor solution is most appropriate.
In IntelliJ, I recommend adding a Live Template:
Use "log" as the abbreviation
Use private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class); as the template text.
Click Edit Variables and add CLASS using the expression className()
Check the boxes to reformat and shorten FQ names.
Change the context to Java: declaration.
Now if you type log<tab> it'll automatically expand to
private static final Logger logger = LoggerFactory.getLogger(ClassName.class);
And automatically reformat and optimize the imports for you.
As for the code example in the question, the standard solution is to reference the class explicitly by its name, and it is even possible to do without getClassLoader() call:
class MyClass {
public static void startMusic() {
URL songPath = MyClass.class.getResource("background.midi");
}
}
This approach still has a back side that it is not very safe against copy/paste errors in case you need to replicate this code to a number of similar classes.
And as for the exact question in the headline, there is a trick posted in the adjacent thread:
Class currentClass = new Object() { }.getClass().getEnclosingClass();
It uses a nested anonymous Object subclass to get hold of the execution context. This trick has a benefit of being copy/paste safe...
Caution when using this in a Base Class that other classes inherit from:
It is also worth noting that if this snippet is shaped as a static method of some base class then currentClass value will always be a reference to that base class rather than to any subclass that may be using that method.
In Java7+ you can do this in static methods/fields:
MethodHandles.lookup().lookupClass()
I wrestled with this myself. A nice trick is to use use the current thread to get a ClassLoader when in a static context. This will work in a Hadoop MapReduce as well. Other methods work when running locally, but return a null InputStream when used in a MapReduce.
public static InputStream getResource(String resource) throws Exception {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
InputStream is = cl.getResourceAsStream(resource);
return is;
}
Simply use a class literal, i.e. NameOfClass.class
Try it
Thread.currentThread().getStackTrace()[1].getClassName()
Or
Thread.currentThread().getStackTrace()[2].getClassName()
getClass() method is defined in Object class with the following signature:
public final Class getClass()
Since it is not defined as static, you can not call it within a static code block. See these answers for more information: Q1, Q2, Q3.
If you're in a static context, then you have to use the class literal expression to get the Class, so you basically have to do like:
Foo.class
This type of expression is called Class Literals and they are explained in Java Language Specification Book as follows:
A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a `.' and the token class. The type of a class literal is Class. It evaluates to the Class object for the named type (or for void) as defined by the defining class loader of the class of the current instance.
You can also find information about this subject on API documentation for Class.
I had the same problem !
but to solve it just modify your code as following.
public static void startMusic() {
URL songPath = YouClassName.class.getClassLoader().getResource("background.midi");
}
this worked fine with me hope it will also work fine with you.
Suppose there is a Utility class, then sample code would be -
URL url = Utility.class.getClassLoader().getResource("customLocation/".concat("abc.txt"));
CustomLocation - if any folder structure within resources otherwise remove this string literal.
Try something like this. It works for me. Logg (Class name)
String level= "";
Properties prop = new Properties();
InputStream in =
Logg.class.getResourceAsStream("resources\\config");
if (in != null) {
prop.load(in);
} else {
throw new FileNotFoundException("property file '" + in + "' not found in the classpath");
}
level = prop.getProperty("Level");
This might be an age old problem and I am sure everyone has their own ways.
Suppose I have some properties defined such as
secret.user.id=user
secret.password=password
website.url=http://stackoverflow.com
Suppose I have 100 different classes and places where I need to use these properties.
Which one is good
(1) I create a Util class that will load all properties and serve them using a key constant
Such as :
Util is a singleton that loads all properties and keeps up on getInstance() call.
Util myUtil = Util.getInstance();
String user = myUtil.getConfigByKey(Constants.SECRET_USER_ID);
String password = myUtil.getConfigByKey(Constants.SECRET_PASSWORD);
..
//getConfigByKey() - inturns invokes properties.get(..)
doSomething(user, password)
So wherever I need these properties, I can do steps above.
(2) I create a meaningful Class to represent these properties; say,
ApplicationConfig and provide getters to get specific properties.
So above code may look like:
ApplicationConfig config = ApplicationConfig.getInstance();
doSomething(config.getSecretUserId(), config.getPassword());
//ApplicationConfig would have instance variables that are initialized during
// getInstance() after loading from properties file.
Note: The properties file as such will have only minor changes in the future.
My personal choice is (2) - let me hear some comments?
Do it the most straightforward way (a class with static values):
package com.domain.packagename
public class Properties {
private static String hostName;
public static getHostName() { return hostName; }
private static int port;
public static int getPort() { return port; }
public static void load() {
//do IO stuff, probably
hostName = ??;
port = ??;
//etc
}
}
I find the first approach to be more verbose than necessary. (Especially if the properties are not expected to change very much.) Also, by using the second approach you can handle casting/type issues when the properties are loaded instead of when they are used.
Your option (2) to keep application specific getters sounds better and clean.
public static final keys from an interface had been a bad design in Java for ages.
I guess my first question is why you want to create an instance of something you're saying is a singleton (you mentioned using code like Util.getInstance()). A singleton only has 1 instance so you shouldn't try to instantiate multiple copies in your code.
If the data is static (like this appears to be) I'd create a singleton and retrieve the values from it.
I don't think there is any significant advantage of one method over the other and I don't think the solution (1) is more secure, just because it provides a property key instead of a java getter for getting passwords.
If I had to chose one though I would take option (2).