Hey guys I am not seeing what I am doing wrong here. I am currently following this tutorial on how to implement the Singleton Pattern for a project and I set up some test files to see if it would work out well with what I'm doing, and as far as I can tell I am following the pattern perfectly and yet I can't seem to access ANY of the methods, this is the third time I've set this up in various ways, and as this is the simplest setup and it still doesn't work right, I am in the dark on whats going on here. I just need what I'm doing wrong here pointed out if at all possible. Here is the code:
DCTest.java (the Singleton Class)
package com.saphiric.simproject.datacontrols;
/**
* Created by Saphiric on 12/30/14.
*/
public class DCTest {
// Singleton Test
private static DCTest dct = new DCTest();
private DCTest(){
// Prevents outside instantiation
}
public static DCTest getInstance(){
return dct;
}
// test variables for making sure it can have dynamic fields
private int INT;
protected void setInt(int newInt){
INT = newInt;
}
protected int getINT(){
return INT;
}
}
DataCore.java (The file I want to access the Singleton Class)
package com.saphiric.simproject.datacontrols;
/**
* Created by Saphiric on 12/29/14.
*/
public class DataCore {
// Singletons Tests
DCTest test = DCTest.getInstance();
test.setInt(0);
public DataController data = new DataController();
public DecisionLocks locks = new DecisionLocks();
}
Your issue is that method calls in Java have to be in a method. So the issue you're having actually has little to do with the Singleton pattern at all, it's that you're trying to make a call in the body of a class, rather than a method. If you tried to compile the following you'd have the same error:
public class HelloWorld{
System.out.println("Hello, World!"); //Err
}
The solution to your problem depends on what you are trying to accomplish.
If you're trying to call setInt(0) at the class load time of the DataCore class (and test was supposed to be a static field), use a static initializer (just the word static instead of a method header) for that statement.
public class DataCore {
// Singletons Tests - static
static DCTest test;
//Called when the DataCore class is loaded.
static{
test = DCTest.getInstance();
test.setInt(0);
}
}
Alternatively, if the field test is actually supposed to be non-static, simply put the setInt call in a constructor:
public class DataCore {
// Singletons Tests - nonstatic
DCTest test;
public DataCore(){
test = DCTest.getInstance();
test.setInt(0);
}
}
Enclose your code of DataCore class into a method.
public class DataCore {
// Singletons Tests
public void work () { // added code in this method.
DCTest test = DCTest.getInstance();
test.setInt(0);
public DataController data = new DataController();
public DecisionLocks locks = new DecisionLocks();
}
}
Related
I came across the following issue when I was trying to unit test my code. If I have a class that creates an instance and for example a getter method like this:
public class Test {
private static Test instance;
private ArrayList<String> arrayList = new ArrayList<String>();
public static Test getInstance() {
return instance;
}
private ArrayList<String> getArrayList() {
return arrayList;
}
}
If now I want to access the arrayList in a test case it would fail, because the list is returned by a non-accessable private method. So trying something like this wouldn't work:
public class AccessTest {
private Test test;
public void accessList(){
test = Test.getInstance();
test.getArrayList();
}
}
So one way to access the arrayList anyway, would probably be to change the visibility to protected. But isn't there a better way to access the method? Is it really necessary to make a method protected only because of a test that needs to access it?
In general, if you have some private methods in your class and you feel that you have problems with testing them, it is a sign of a bit of a code smell. It shows that too many functionality is hidden behind private wall.
You could change visibility of such method to package protected, so JUnit test will see it. There is also a Google Guava annotation #VisibleForTesting or something like that. But again - this is a sign of wrong class design.
Think of extracting such method to a separate class and make that methods public then.
For example, take a look at the following code:
class ReportCreator {
public File createSomeImportantReport(LocalDate date) {
String fileName = provideFileName(date);
File result = new File(fileName);
return result;
}
private String provideFileName(LocalDate date) {
// ... some complex business logic to generate file name based on date... ;)
return fileName;
}
}
There is a private method provideFileName() that does some complicated things and let's say it's hard to test if you would test only createSomeImportantReport().
See what changes if you externalize that functionality.
class ReportCreator {
private FileNameProvider fileNameProvider;
public File createSomeImportantReport(LocalDate date) {
File result = new File(fileNameProvider.provideFileName(date));
return result;
}
}
class FileNameProvider {
public String provideFileName(LocalDate date) {
return ......;
}
}
You now have option to test that thing separately, focus on what's important in that particular case.
Despite the fact that I don't see a use case for a private getter, you can use the package private access level. This is the default access level so you don't have to specify it. You can then test it by adding the test class in the same package name in the test directory. For instance the class is located in src/main/java/application and the test class can then be located in src/test/java/application.
Use Java Reflection for that:
Test test = new Test();
Method getArrayListMethod = test.getClass().getDeclaredMethod("getArrayList", null);
getArrayListMethod.setAccessible(true);
ArrayList<String> list = (ArrayList<String>) getArrayListMethod .invoke(test);
System.out.println(list); // Prints the list
Create your Test object, use the method getClass() and get the method declared on that class by its name.
Then set that method accessible dynamically. If you know the data type that it returns, then cast it to it.
I facing a real hard problem in my code snippet.
I want to learn how to use Interface in Java the correct way.
So for this I have my Application-Class...
package inversionUsage;
public class Application {
public static void main(String [] args) {
String standard = "Standard version!";
if (FeatureDecisions.checkEnabledFeatures("new-feature1")) {
System.out.println("Implement new feature...");
}else {
System.out.println(standard);
}
}
}
Then I made a Interface...
package inversionUsage;
public interface AppConfiguration {
boolean isEnabled(String searchFeature);
}
I want to use the Interface in another class:
package inversionUsage;
import java.util.Arrays;
public class FeatureDecisions implements AppConfiguration{
public String [] enabledFeatures;
public String [] _implNewFeature = fetchFeatureTogglesFromSomehere();
public static boolean checkEnabledFeatures(String searchFeature) {
return isEnabled(searchFeature);
}
#Override
public boolean isEnabled(String searchFeature) {
if (Arrays.asList(_implNewFeature).contains(searchFeature)) {
return true;
}else {
return false;
}
}
private String [] fetchFeatureTogglesFromSomehere() {
// TODO get the CONFIG from somewhere
enabledFeatures = new String [2];
enabledFeatures[0] = "new-feature1";
enabledFeatures[1] = "new-feature2";
return enabledFeatures;
}
}
So the workflow is:
1. I start the Application
2. Main method checks the enabled features via FeatureDecisions.java
3. In Feature Decisions i implemented the Interface
I getting the error:
Cannot make a static reference to the non-static method isEnabled(String) from the type FeatureDecisions
May Someone can help me out?
The only way to use an instance method is to have an instance on which to call it. Your checkEnabledFeatures is static, so it doesn't receive an instance you can use (as this). To use an instance method, it would need to create an instance. But obviously that's not what you want here.
Java's interface construct is for defining the interface that instances implement. Java doesn't have the concept of a "static interface" that a class must implement. On the rare occasions when that's needed, it's usually implemented using reflection (perhaps with a class-level annotation to indicate that the class has the necessary feature).
You would have to instantiate the FeatureDecisions class.
public static boolean checkEnabledFeatures(String searchFeature) {
return new FeatureDecisions().isEnabled(searchFeature);
}
or make all members static.
Additional info: There are frameworks like togglz that do this for you.
There's no way to do that. The closest can get is to use the singleton pattern (though lots of people - myself included - would discourage it).
public enum FeatureDecisions implements AppConfiguration
{
INSTANCE;
public String [] enabledFeatures;
public String [] _implNewFeature = fetchFeatureTogglesFromSomehere();
public boolean checkEnabledFeatures(String searchFeature) {
return isEnabled(searchFeature);
}
#Override
public boolean isEnabled(String searchFeature) {
//...
}
}
Your call would then change from:
FeatureDecisions.checkEnabledFeatures(...)
to
FeatureDecisions.INSTANCE.checkEnabledFeatures(...)
It's also worth noting that checkEnabledFeatures doesn't actually do anything besides defer to isEnabled. You could scrap the former and just call the latter directly.
I'm confused about an essential thing in java.
public class InitItself1 {
public InitItself1(){}
private InitItself1 me = new InitItself1();
}
Of course I know that the StackOverFlowError will be occurred when creating an instance of the above class. The above class will be initiated recursively itself because of the initiation of the variable "me".
But,
public class InitItself2 {
public InitItself2(){}
private static InitItself2 me = new InitItself2();
}
Of course the outcome of the above class, "InitItself2" is different to the prior class, "InitItself1". This works just fine, no error occurred. As I know, initiating static variables and executing static blocks are performed when classes in which static variables and blocks are loaded.
What makes me confused is that I think it's the same that the variables, "me" of both classes, "InitItself1" and "InitItself2" are initiated, and also they have references to their classes in which they are, so it looks that "initiating recursively" would happen in initiating both classes.
What is the point that I'm missing?
Good answer please.
Thanks :)
You are not going to get StackOverFlowError in the second case. As you have said yourself, static variables are initiated when the class is loaded, and because a class is only loaded once, the static InitItself2 me will only be instantiated once. Creating a new object with constructor doesn't require the class to be reloaded.
public final class InitItself {
static {
System.out.println("Class is loaded");
}
private static InitItself me = new InitItself();
static {
System.out.println("me is instantiated");
}
public InitItself() {
System.out.println("Constructor called, me=" + me);
}
public static void main(String[] args) {
System.out.println("START");
InitItself i = new InitItself();
System.out.println("FINISH");
}
}
Gives the following output
Class is loaded
Constructor called, me=null
me is instantiated
START
Constructor called, me=oop.InitItself#6ff3c5b5
FINISH
I have a class with a method that takes a single parameter. This parameter is a nested class inside the mocked class, but it is private (And static but I don't think that makes much of a difference to this). How do I go about mocking this method?
Example:
public class myClass {
public anotherObject;
public myClass(AnotherObject anotherObject) {
this.anotherObject = anotherObject;
}
public void exec() {
//Some instructions ...
//This second method is inside another completely seperate class.
anotherObject.secondMethod(new NestedClass());
}
private static class NestedClass {
public NestedClass() {
//Constructor
}
//Variables and methods, you get the picture
}
}
In the above example secondMethod(...) is the method that I want to mock.
All attempts to find other examples of this problem just return results relating to mocking a single private nested class, or mocking static classes, which aren't completely relevant to this and don't seem to provide any work around that I can figure out.
EDIT:
I'm looking for some sort of solution that looks like this:
#Test
public void testExec() {
AnotherObject anotherObject = mock(AnotherObject.class);
when(anotherObject.secondMethod(any(NestedClass.class))).thenReturn(0);
MyClass testThisClass = new MyClass(anotherObject);
}
Notes: I'm not allowed to make modifications to the code I'm afraid, I am only allowed to create these tests to make sure the current implementation works later down the line when modification are made to it.
If I am understanding the requirement correctly, add one method say executeSecondMethod(). Call this method in your main method class.
public class myClass {
public void exec() {
//Some instructions ...
secondMethod(new NestedClass());
}
public void secondMethod(NestedClass example) {
//Some instructions that I want to just mock out...
}
private static class NestedClass {
//Variables and methods, you get the picture
}
public static executeSecondMethod(){
secondMethod(new NestedClass()); // pass the nested class object here
}
}
public class mainClass{
public static void main(){
executeSecondMethod();
}
}
i Want to make a class and some methods in that class which interact with database.
Many other classes Should call that methods.
Q1:is it possible to create only one instance of that class for others ?
Q2:Can i give methods as Static?
Q3:Is there is any alternative solution for static and singleton for java database?
I have not used singletons in Java yet. However, there's a pretty good discussion on the subject at http://c2.com/cgi/wiki?JavaSingleton
Basically, you will make your constructor private along with a private static final instance variable. Then you will need a public static getInstance method that returns your instance. It gets a bit more complicated if you need to be thread safe, so read the linked article.
You can also use an enum with a single variable INSTANCE like below:
public enum EmployeeDAO {
INSTANCE;
static{
//Initialize connection info etc.
init();
}
private EmployeeDAO(){
//Constructor stuff
}
public Employee getEmployeesById(int id){
//Replace this with your data retrieval logic
return null;
}
public Employee getDeadBeatEmployees(){
//Replace this with your data retrieval logic
return null;
}
public Employee getAllStars(){
//Replace this with your data retrieval logic
return null;
}
public static void init(){
}
}
public class Employee{}
public class SillyCanuck{
public static void main(String args[]){
EmployeeDAO.INSTANCE.getEmployeeById(5);
}
}