Why use a static declaration when initializing a new non-static object - java

I apologize if this is redundant, but I was not able to find a similar question. And, TBH, I don't even know how to frame the question properly.
This is a from a review question from the Java 8 OCA study guide. The question is about static initializers, which I understand just fine. There is however a line of code that I don't get, and because the question isn't about it, there is not a very good explanation of it.
private static Rope rope = new Rope();
So this isn't about Singletons or static classes. I don't understand why you would initialize an object like this. And, if there is a good reason why you can and would do this, what is the reason?
Would someone kindly point me in the direction of an explanation? Like I said, I'm not even sure what this is properly called, so am having a hard time finding a good answer on my own.
Edit to put in the entire class:
import rope.*;
import static rope.Rope.*;
public class RopeSwing
{
private static Rope rope1 = new Rope("rope 1");
private static Rope rope2 = new Rope("rope 2");
{
System.out.println(rope1.length);
}
public static void main(String[] args) {
rope1.length = 2;
rope2.length = 8;
System.out.println(rope1.length);
}
}

This makes a single Rope instance available to the whole class - it will be shared by all instances of the class this is declared in. This can be useful when there's some shared information or state all instances should rely on.
Often, private static fields are also declare final, which makes them constants (assuming the type of the field is immutable). Looking at your full example, I suspect the author should have made them private static final.
For example:
public class Foo {
private static Rope rope = new Rope();
private int value;
public Foo(int value) { this.value = value; }
#Override public String toString() {
return "static rope: " + rope + " instance value: " + value;
}
}
If you create several instances of Foo (new Foo(1);, 'new Foo(2), etc.) they will all share the same rope instance, and new Rope() will only have been invoked once (when the class is first loaded).
An example of a non-constant static field might be a shared counter. Suppse you want to uniquely identify every instance of an object that gets constructed, anywhere in your application. You can do so with an AtomicInteger, which is essentially a thread-safe int:
public class Unique {
// despite being final this is not a "constant" because it's mutable
private static final AtomicInteger counter = new AtomicInteger();
private final int id;
public Unique() {
id = counter.getAndIncrement();
}
#Override public String toString() { return "ID: " + id; }
}
Give it a try - every instance of Unique will have a unique ID.
In your example code there's an instance initializer, which will be invoked when creating a new instance (hence after the static fields have been initialized).

Related

Is this a proper way to share variables among many objects without a singleton?

So, I have a program where many objects of several different classes need to read some (many) variables from an object of 'class X', to give it a name. A quick and simple way of doing this would be to make a singleton, which wouldn't be X itself but a class it access to. I've done this, and later on it started feeling dirty, and many seem to agree, so I'd like to change my design for this. I haven't found any ideas to replace this pattern, though, just "don't do it" and "pass the data around." I'd like my data to be read-only, though. I haven't found mention of any other patterns.
The best I've got to share these read-only variables, which seems perfectly fine to me, is to have a class SharedVars for the data to share, but in the form of an inner class. It's inside Data, which is an outer class that is able to modify SharedVars, encapsulating what's meant to be read-only for the other classes. Basically, any class that wants to read these variables needs a Data.SharedVars object:
public class Data {
public static class SharedVars {
private int encapsulatedData;
public int getData() {
return encapsulatedData;
}
}
// no one should touch this but Data:
static private SharedVars sharedData;
Data() {
sharedData = new SharedVars();
}
public SharedVars getDataRef() {
return sharedData;
}
// here's where this class (and only this class, whenever it's told)
// modifies the encapsulated data:
void manipulateData() {
sharedData.encapsulatedData = 5;
}
}
One of the classes that depends on this would take this form:
public class Client {
// This class can't access the data directly
// so it'll use Data's getter:
Data.SharedVars vars;
public Client(Data.SharedVars vars) {
this.vars = vars;
// vars.encapsulatedData = 5; // is not allowed, since the field is private (which is what I want)
}
public void go() {
// the proper way to get its hand on the data:
int data = vars.getData();
System.out.println("The data is " + data);
}
}
Main is not needed in this example, but I'll leave it here anyway:
public class Main {
static Data dataControl;
static Client client;
public static void main(String[] args) {
dataControl = new Data();
client = new Client(dataControl.getDataRef());
dataControl.manipulateData();
client.go();
}
}
Is this proper? Or, what are the risks here? Notice I don't want the objects to copy them for themselves, since they'll be changing all the time, and I don't entirely like the idea of having a reference to the 'class X' I've mentioned before.

Legitimate uses for static initializer?

I remember a couple years ago I was using static initializers to call class-level setup operations. I remember it having very bizarre behaviors and I just decided to steer clear from them. Maybe it was because I was messing up the top-bottom order or being a newbie. But I am encountering a need to revisit them and I want to make sure there is not a better way that is just as concise.
I know it is not fashionable, but I often have data-driven classes that maintain a static list of instances imported from a database.
public class StratBand {
private static volatile ImmutableList<StratBand> stratBands = importFromDb();
private final int minRange;
private final int maxRange;
private static ImmutableList<StratBand> importFromDb() {
//construct list from database here
}
//constructors, methods, etc
}
When I have dozens of table-driven classes like this one, this pattern is very concise (yes I know it tightly couples the class with one source of data/instances).
However, when I discovered the goodness of Google Guava I want to use the EventBus to update the static list when a certain event posted. I would create a static final boolean variable just to call a static method that initialized the registration.
public class StratBand {
private static volatile ImmutableList<StratBand> stratBands = importFromDb();
private static final boolean subscribed = subscribe();
private final int minRange;
private final int maxRange;
private static ImmutableList<StratBand> importFromDb() {
//construct list from database here
}
//constructors, methods, etc
private static boolean subscribe() {
MyEventBus.get().register(new Object() {
#Subscribe
public void refresh(ParameterRefreshEvent e) {
stratBands = importFromDb();
}
});
return true;
}
}
This got annoying very quickly, because the compiler would throw warnings over the subscribed variable never being used. Also, it just added clutter. So I'm wondering if it is kosher to use the static initializer, and there really is no better way if I do not decouple this into two or more classes. Thoughts?
public class StratBand {
private static volatile ImmutableList<StratBand> stratBands = importFromDb();
static {
MyEventBus.get().register(new Object() {
#Subscribe
public void refresh(ParameterRefreshEvent e) {
stratBands = importFromDb();
}
});
}
private final int minRange;
private final int maxRange;
private static ImmutableList<StratBand> importFromDb() {
//construct list from database here
}
//constructors, methods, etc
}
So I'm wondering if it is kosher to use the static initializer
The funny thing is that
private static final boolean subscribed = subscribe();
and
private static final boolean subscribed;
static {
subscribed = subscribe();
}
get compiled to exactly the same bytecode. So using the needless static variable is strictly worse.
But until we are ready to scale up to a DI-driven framework,
Discover Guice. Don't call it framework (though it is). It's easy to use and let's you get rid of static.
Or do it manually. Rewrite your class by dropping all static modifiers and pass it everywhere you need it. It's rather verbose sometimes, but stating dependencies explicitly allows you to test classes in isolation.
The way it is, you can't test StratBand without hitting the database, no matter how trivial the method under test is. The problem is the coupling of every StratBand instance to the list of all StratBands.
Moreover, you can't test the behavior dependent on the stratBands contents as it always get loaded from the DB (sure, you can fill your DB correspondingly, but it's a big pain).
For starters, I'd create StratBandManager (or StratBands or whatever name you like) and move all the static functionality to it. In order to easy the transition, I'd create a temporary class with static helpers like
private static StratBandManager stratBandManager = new StratBandManager();
public static ImmutableList<StratBand> stratBands() {
return stratBandManager.stratBands();
}
Then deprecate it all and replace it by DI (using Guice or doing it manually).
I find Guice useful even for small projects. The overhead is tiny as often there's no or hardly any configuration.

how to use singleton pattern for sequence number creation in java

I have an Orders class and i need to have a singleton pattern to be able to create a sequence number for each order processed. How do i implement this?
My order class has an Order_ID, Customer_ID, Order_desc and Ordered_qty. There needs to be a sequence number created for each order processed using the singleton pattern.
This may be one of those X/Y problems, where you think Y is a solution to X, so you ask for help with Y, but perhaps there is a better solution.
Strictly speaking, to implement a singleton, all you need is a class whose only constructors are private, a static reference to an instance of the class as a class field, and a public getInstance method. Then create an instance method which returns the next number in line.
public class MySingleton {
private static MySingleton instance = new MySingleton();
private volatile int next = 0;
private MySingleton() {
// prevent external instantiation of a singleton.
}
public static MySingleton getInstance() {
return instance;
}
public synchronized int getNextSequence() {
return next++;
}
}
There are many flaws with this solution to your problem, some are just basic OOP design and some are more systemic:
A singleton that does not implement or extend any types is worthless. You could just use all static methods instead. Singletons are useful if you are writing a class that implements an interface and that interface is used by somebody else, but you only want a single instance as an implementation detail. This type of singleton is an attempt to make a global variable look like it is not a global variable.
This will not survive application restarts. If these sequences are being used to identify data that is stored externally or shared, you will end up repeating the same numbers when the application is restarted.
If you deploy multiple instances of the application who read and write to a common persistent storage, like a database, they will re-use the same numbers because the sequence is only tracked within the JVM.
Databases are already exceptionally good at this. Trying to re-invent it in the application tier seems.... inappropriate.
Although I agree #Elliott Frisch that the question itself sounds strange. However if you indeed have to generate IDs yourself here is the prototype that implements classic version of Singleton pattern.
public class IdGenerator {
private static IdGenerator instance;
private int id = 0;
private IdGenerator(){}
private static IdGenerator getInstance() {
synchronized(IdGenerator.class) {
if (instance == null) {
instance = new IdGenerator();
}
return instance;
}
}
public int nextId() {
return id++;
}
}
Please note that word "classic". There are a lot of possible improvements of Singleton pattern and there are hundreds of articles that explain them.
The key aspect is to use a single AtomicLong as the singleton. You may model it like this:
class Orders {
private static final AtomicLong NEXT_ID = new AtomicLong();
static Order newOrder(Customer customer, String description, int quantity) {
return new Order(orderId(), customer, description, quantity);
}
private static long orderId() {
return NEXT_ID.incrementAndGet();
}
}
class Order {
private final long orderId;
private final long customerId;
private final String description;
private final int quantity;
Order(long orderId, Customer customer, String description, int quantity) {
this.orderId = orderId;
this.quantity = quantity;
this.customerId = customer.getCustomerId();
this.description = description;
}
}
class Customer {
public long getCustomerId() {
throw new UnsupportedOperationException("not yet implemented");
}
}

Constructors and Strings Part 2Letter Example

The issue I'm having is, while I believe that I've have set up everything correctly in the constructor, when I try to call the instance variable from of my new Letter instance fromto I seem to keep getting an error saying that the compiler can not find variable fromto. The goal is to get Dylan to appear in with the Text.
public class Letter {
private String from; // Sets from instance variable to be stored
private String to; /// Sets to instance vaariable to be stored
public Letter(String from, String to) {
this.from = from;
this.to = to;
}
public Letter() {
Letter fromto = new Letter("Dylan", "April");
}
public static void main(String[] args) {
System.out.println("Dear " + fromto.from);
}
}
First of all, you should probably learn more about variable scope in Java. (Reading Sun's tutorials about Object-oriented Java-programming is probably a good idea)
The problem here is that the variable fromto is declared in a constructor and thus is only available from the scope of the constructor. Instead, get rid of that constructor (unless you really want to keep it, in which case you should make sure to initialize your from and to variables properly) and move the variable to your main function.
public class Letter {
private String from; // Sets from instance variable to be stored
private String to; /// Sets to instance vaariable to be stored
public Letter(String from, String to) {
this.from = from;
this.to = to;
}
public static void main(String[] args) {
Letter fromto = new Letter("Dylan", "April");
System.out.println("Dear " + fromto.from);
}
}
You need to first create a new instance of your Letter class before you can invoke fields and getter/setter-methods on that instance/object.
public static void main(String[] args)
{
Letter myLetter = new Letter();
System.out.println(myLetter.from);
}
Note the call on your private field from only succeeds as main is defined in the same class and therefore the created myLetter provides access to the field.
In practice you would define public setters and getters to access the private field.
You need to instantiate your Letter in the right scope. If you if you only need it inside the main method, the best place to create your instance is right at the beginning of the method block:
public class Letter {
private String from; // Sets from instance variable to be stored
private String to; /// Sets to instance vaariable to be stored
public Letter(String from, String to) {
this.from = from;
this.to = to;
}
public Letter() {
}
public static void main(String[] args) {
Letter fromto = new Letter("Dylan", "April");
System.out.println("Dear " + fromto.from);
}
}
About the no-args constructor, it is a good practice to declare one if the instance variables from and to are optional, so that you can also instantiate letter with the syntax new Letter(). If you do not declare any constructors, the compiler provides a empty constructor by default.
Actually, whenever you can, it is a good thing to follow JavaBeans conventions. Quoting Wikipedia:
The class must have a public default constructor (no-argument). This
allows easy instantiation within editing and activation frameworks.
The class properties must be accessible using get, set, is (used for
boolean properties instead of get) and other methods (so-called
accessor methods and mutator methods), following a standard naming
convention. This allows easy automated inspection and updating of bean
state within frameworks, many of which include custom editors for
various types of properties. Setters must receive only one argument.
The class should be serializable. It allows applications and
frameworks to reliably save, store, and restore the bean's state in a
fashion independent of the VM and of the platform.
Remove
public Letter(){
Letter fromto= new Letter("Dylan", "April");
}
then:
public static void main(String[] args){
Letter fromto= new Letter("Dylan", "April");
System.out.println("Dear " + fromto.from);
}

How to effectively use static methods?

I am never quite sure that I am using static methods correctly. I understand how they work.
Let's say I have this class called Player(Java):
private int money;
private int lot;
private String piece;
private int playerNum;
public Player(String _piece, int _playerNum)
{
piece = _piece;
lot = 0;
playerNum = _playerNum;
money = 20000;
}
public int getMoney()
{
return money;
}
public int getLot()
{
return lot;
}
public String getPiece()
{
return piece;
}
There are some other methods + setters, but they are specific to the player object I create, now let's say I have a static method like this:
private static int numOfPlayers;
public static int numPlayers()
{
return numOfPlayers;
}
Where should this numOfPlayers method be placed?
Should it be put in my Player class? And should I increment the numOfPlayers varible everytime a new isntance of the player object is created?(via the constructor)
Or, should I have I have the method in my Game class as non-static and just call the method everytime I create a new Player.
Static fields and methods are supposed to represent stateless attributes of a class; i.e. not pertinent to a particular object.
But be careful with multithreading with statics since the whole class has to be locked rather than just one object. This can lead to concurrency bottlenecks.
As for your numOfPlayers, you'll probably end up having a collection of players developed somewhere else, in which case that function will be a method on that collection not in the player class.
Ideally, in my opinion at least, an individual player should not really be concerned about the players collection. Therefore a static function such as the one you propose would not be good design.
It is a matter of design, which obviously includes a lot of personal preference.
You really should have a look at the factory design pattern, which is a good way of handling such cases. Here, you could have a
public class PlayerFactory {
private int numPlayers = 0;
public int getNumPlayers() { ... }
public Player makeNewPlayer(...) { ... }
}
that takes care of A) incrementing the player count appropriately.
Depending on your exact use case and code style, you may prefer one variation or another. But it is good to know these patterns and recognize them. And document them. By calling a class SomethingFactory you do hint for other developers that this class follows the factory pattern, for example.
Note that I did not need to use static in above example, assuming that the factory may only be instantiated once. It is common to see the constructor private and instead the class then has a public static final instance only.
You could also call this class Game or Players...
how about you have a List of Players in your game and the number of players is the size of the List.
When you think you should use static for some functionality, don't do it!
Just play along the old rule to never use anything static until you are old and wise and where you perhaps can use it for some very special corner case.
You can create it like this:
Have class Player like you have
Create class Players
class Players
{
private List<Player> players = new List<Players>;
public void AddPlayer(Player pl)
{
this.players.add(pl);
}
public int GetPlayersCount()
{
return this.players.size();
}
}
If you want, you can make this class "static" using Singleton. But try to avoid static classes.
class Players
{
private List<Player> players = new List<Players>;
private static Players instance;
private Players () {};
public static Players getInstance()
{
if (instance == null)
{
instance = new Players ();
}
return instance;
}
public void AddPlayer(Player pl)
{
this.players.add(pl);
}
public int GetPlayersCount()
{
return this.players.size();
}
}
And use it like this
Players players = Players.getInstance();
players.AddPlayer(....)
I would have the list of Players in another class, e.g. Game as you suggested.
Something like
class Game {
private final List<Player> players = new ArrayList<Player>();
public int getNumOfPlayers() {
return players.size();
}
public void addPlayer(final Player player) {
players.add(player);
}
...
You add a player via your instance of Game, game via game.addPlayer(newPlayer), and get the number of players via game.getNumOfPlayers().
The List of players is dynamically allocated.
As for static or not static, I prefer here the non static version, as the players are part of a Game, and one could consider they may be several games - and players would be part of an instance of Game.

Categories

Resources