if i need use a global class what is the best option and why?
public class Global {
public static JSONObject GetJsonResquest(String url){
....
};
}
and then call Global.GetJsonResquest(url) in my activity
OR
public class Singleton {
private static Singleton ourInstance = new Singleton();
public static Singleton getInstance() {
return ourInstance;
}
private Singleton() {
}
public JSONObject GetJsonResquest(String url){
.....
}
}
and then use via Singleton.getInstance().GetJsonResquest("Asd");
When I need a global static variable, I like to group them into a class like
public class MyConstants {
public static final int TIMEOUT = 10000;
}
To use it, i can call it like
long tick = System.currentThreadMillis();
while((System.currentThreadMillis() - tick) < MyConstants.TIMEOUT){
Thread.sleep(1000);
}
So that when I change the TIMEOUT value, I don't have to change other classes that calls it
For global static method, I use them like
public class Utility{
public static boolean isStringValidJson(String jsonString){
return false;
}
}
Same reason as above. When I change isStringValidJson, other classes that calls it don't change
I do use the singleton pattern but only when I override the Application class. However, I set the instance value in OnCreate instead. This means that if OnCreate was not called, getInstance will return null
public class MyApplication extends Application {
private static MyApplication instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static synchronized MyApplication getInstance(){
return instance;
}
}
Related
For instance I want to take this
public class SomeClass {
public static final String GREET_STRING = "Hello!";
//...
and change it to something like:
public class SomeClass {
public static final String GREET_STRING = getString(R.string.greet_string);
//...
Can this be done or do I need some kind of Context instantiation to get the resources for the string loading?
To use getString() you will need a context. A Resource string cannot be static final because it is possible for String resources to change as you change Locales (if you have multiple String files such as strings.xml (us) and strings.xml (uk))
Try this:
public abstract class SomeClass extends AppCompatActivity {
public static String GREET_STRING(Context context) {
if (context == null) {
return null;
}
return context.getResources().getString(R.string.greet_string);
}
}
Res/Value/String:
<resources>
<string name="greet_string">Hello!</string>
</resources>
Call SomeClass from MainClass
public class MainClass extends SomeClass {
private final static String TAG = MainClass.class.getName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// call SomeClass from MainClass
Log.i(TAG, SomeClass.GREET_STRING(this));
}
}
There are two ways access the string inside the class which is not extending Activity or Fragment.
Pass Context or Activity to class constructor
public class SomeClass {
private Context context;
public SomeClass(Context context) {
this.context = context;
}
public static final String GREET_STRING = context.getString(R.string.greet_string);
}
The second way is if you don`t want to pass context to class. You need to create an instance of the Application and static function get instance.
public class App extends Application {
private static App instance = null;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static App getInstance() {
// Return the instance
return instance;
}
}
public class SomeClass {
public static final String GREET_STRING = App.getInstance().getString(R.string.greet_string);
}
I've write a Singleton, but this singleton need a Context as a param to initialize itself. As the Context is used only once in its constructor, I would not like to add it in getInstance(Context). After thinking more, I came out the following answer:
public class Singleton {
private static Context sContext;
public static void init(Context context) {
sContext = context;
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder {
private static Singleton INSTANCE = new Singleton();
}
private Singleton() {
if (sContext == null) {
throw new IllegalArgumentException("#init should be called in Application#onCreate");
}
// Initialize the Singleton.
// .....
// After the constructed, remove the sContext.
sContext = null;
}
}
It's well, with a class method init called in Android/Applicaiton#onCreate method.
It's not instance the SingletonHolder.INSTANCE, as it's not loaded.
Could some give someone advice on my solution。Thanks!
With the help of # WarrenFaith I changed my code.
public class Singleton {
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder {
private static Singleton INSTANCE = new Singleton();
}
private Singleton() {
final Context context = BaseApplication.getApplication();
// Initialize the Singleton.
// .....
}
}
public class BaseApplication extends Application {
private static Application sApplication;
public static Application getApplication() {
return sApplication;
}
#Override
public void onCreate() {
super.onCreate();
sApplication = this;
}
}
Why not using a way easier solution:
public class Singleton {
private final static Singleton mInstance = new Singleton();
private final static Context sContext;
private Singleton() {
sContext = MyApplication.getInstance();
// do more
}
public static Singleton getInstance() {
return mInstance;
}
}
That is a pretty bullet proof singleton pattern.
Of course you need to implement your application class to be a singleton but by definition it already is.
public class MyApplication extends Application {
private static MyApplication mInstance;
#Override
protected void onCreate() {
super.onCreate();
mInstance = this;
// create your Singleton!
Singleton.getInstance();
}
public static MyApplication getInstance() {
return mInstance;
}
}
I need a class able to return instances of itself. I like method used by a singleton pattern that return only once instance of class. But I need that it return more than one instance.
This is my singleton pattern. How can I modify it to get it able to return more than one instance?
public class GrigliaImpl implements Griglia{
private static GrigliaImpl istanza;
private JTextField[][] griglia;
private Color color;
public GrigliaImpl(){
}
#Override
public int getColumn() {
return griglia[0].length;
}
public JTextField[][] getMatrice(){
return this.griglia;
}
#Override
public int getRow() {
return griglia.length;
}
#Override
public void setColor(Color x) {
this.color=x;
}
#Override
public Color getColor() {
return color;
}
public void set(int row,int column){
this.griglia= new JTextField[row][column];
}
public static GrigliaImpl getIstanza(){
if(istanza == null){
istanza = new GrigliaImpl();
}
return istanza;
}
}
You are talking about the factory pattern:
public class MyClass() {
}
public class MyClassFactory() {
public static getNewInstance() {
return new MyClass();
}
}
The factory method can be included in your class, you don't need a separate factory class.
Your requirements are controversial. If you want to have a singleton - then you will have one instance of this class by definition. If you want to have many instances, then it can't be singleton.
To create a singleton, you need to make your constructor private and add static method to get an instance of your class, which is kept as a static field. (http://en.wikipedia.org/wiki/Singleton_pattern)
If you want to return the same instance of class, after invoking its methods, consider using Builder pattern (http://java.dzone.com/articles/dive-builder-pattern).
public class GrigliaImpl implements Griglia {
private static GrigliaImpl instance;
private GrigliaImpl() {
}
public static GrigliaImpl getInstance() {
if (instance == null) {
instance = GrigliaImpl();
}
return instance;
}
public GrigliaImpl doSomething() {
// do something
return this;
}
}
Default behavior of every class that has a public contructor is to create and return new instances of that class using new operator. but if you specifically want instances through a getInstanceMethod than make constructor private and
replace
public static GrigliaImpl getIstanza(){
if(istanza == null){
istanza = new GrigliaImpl();
}
return istanza;
}
with
public static GrigliaImpl getIstanza(){
return new GrigliaImpl();
}
But to me that does not serve any purpose. But you can still do it :)
I am trying to write a Singleton Lazy Loading Pattern. Here is the class:
public class IMDBLookup {
private static class LazyLoad {
private static final IMDBLookup IMDB_LOOKUP;
static {
IMDB_LOOKUP = new IMDBLookup();
}
}
public static IMDBLookup getInstance() {
return IMDBLookup.LazyLoad.IMDB_LOOKUP;
}
}
I am wondering whether or not I am doing it in a right way?
Thanks in advance.
I prefer to use enum for simplicity.
public enum IMDBLookup {
INSTANCE;
// add fields and methods here.
}
That is correct. You may want to simplify the inner (holder) class as private static final IMDBLookup IMDB_LOOKUP = new IMDBLookup(); for brevity (to get rid of the static initializer block.)
public class IMDBLookup {
private IMDBLookup(){
// without this I do not get why is it a singleton
// anyone could create instances of your class by the thousands
}
private static class LazyLoad {
private static final IMDBLookup IMDB_LOOKUP;
static {
IMDB_LOOKUP = new IMDBLookup();
}
}
public static IMDBLookup getInstance() {
return IMDBLookup.LazyLoad.IMDB_LOOKUP;
}
}
and you should probably use an enum (not completely sure I do this right)
public class IMDBLookup {
private IMDBLookup(){
}
private static enum LazyLoad {
IMDB_LOOKUP_INSTANCE;
private static final IMDB_LOOKUP = new IMDBLookup();
}
public static IMDBLookup getInstance() {
return LazyLoad.IMDB_LOOKUP_INSTANCE.IMDB_LOOKUP;
}
}
The advice you to think about clone & serialize
import java.io.Serializable;
public class DBConnectionInner implements Cloneable, Serializable {
private static final long serialVersionUID = 1173438078175185035L;
#Override
protected Object clone() throws CloneNotSupportedException {
return new CloneNotSupportedException("CLONE NOT SUPPORT FOR SINGTELTON");
}
protected Object readResolve() {
return getInstance();
}
private DBConnectionInner() {}
static DBConnectionInner getInstance() {
System.out.println("DBConnectionInner getInstance");
return LazyInit.instance;
}
public static class LazyInit {
private static final DBConnectionInner instance = new DBConnectionInner();
}
}
I have a class that looks similar to this, and findbugz is complaining about the 'write to the static field from the instance method' (initialize(), and killStaticfield()). I can't set the static field in the ctor.
What is the best fix for this issue?
Would putting staticField in an AtomicReference suffice?
public class Something
{
private static SomeClass staticField = null;
private AnotherClass aClass;
public Something()
{
}
public void initialize()
{
//must be ctor'd in initialize
aClass = new AnotherClass();
staticField = new SomeClass( aClass );
}
public void killStaticField()
{
staticField = null;
}
public static void getStaticField()
{
return staticField;
}
}
Staying as close as possible to your original design...
public class Something {
private static volatile SomeClass staticField = null;
public Something() {
}
public static SomeClass getStaticField() {
if(Something.staticField == null)
Something.staticField = new SomeClass();;
return Something.staticField;
}
}
Refer to your static variable via the class name, that will remove the findbugz warning.
Mark your static variable as volatile, which will make the reference safer in a multithreaded environment.
Even better would be:
public class Something {
private static final SomeClass staticField = new SomeClass();
public Something() {
}
public static SomeClass getStaticField() {
return Something.staticField;
}
}
The question is what you want to do with the static field. If it changes for every class you create it might not be a good idea to have it static at all. If it gets initialized only once you should just lazily initialize it as a singleton.
public class Something
{
private static SomeClass staticField = null;
public Something()
{
}
public static SomeClass getStaticField()
{
if(staticField == null)
staticField = new SomeClass();;
return staticField;
}
}
Remove static from staticField if it should not be static.
Make kill and getStaticField static themselves. And you usually reference static by the class name, not by an (implicit) this, to make very clear that it is static and may cause unexpected consequences in other thReads.
When in doubt, don't use statics for non-constant fields.
The best way is not to do it, try to find a better design patern.
If really necessary this will work and make findbugs/spotbugs not complain.
public class Something
{
private static SomeClass staticField = null;
public Something()
{
}
private void setStaticField(SomeClass value){
staticField=value;
}
public static SomeClass getStaticField()
{
if(staticField == null)
setStaticField(new SomeClass());
return staticField;
}
}