Getting a subclass's static data - java

I have a class Player, that needs to get a Location class. Each location class extends Location, which has a method get() that returns a static instance.
If the character has a string referring to the name of the location extension class, how can I get the instance?
Character:
public class Player {
public static Location getLocation() {
try {
//return location
} catch (Exception ex) {
Logger.getLogger(Player.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
Location:
public class Location{
protected static Location singleton;
public static Location get() {
return null;
}
Location class:
public class Finleydale extends Location{
public static Location get() {
if (Finleydale.singleton == null) {
Finleydale.singleton = new Finleydale();
}
return singleton;
}
}
I have multiple location extensions, and I have the singleton in the location class, so all location extensions have it; and the singleton is static because there is only one version of the location.
Can someone help me with this?

The way you declared the static field in the base class means you have only one reference in the entire program. If you have more than one subclass, and each one assigns to it, then each one is assigning to the same (static) field in the Location base class. I think you want a separate singleton in each subclass.
If you want to look up a particular location by key (say a string value), then I don't think the Singleton pattern is quite what you are looking for. I would create a "location registry" class, something like this:
public class LocationRegistry
{
private static final Map<String, Location> registry;
static
{
final Map<String, Location> _registry = new HashMap<>();
_registry.put("Finleydale", new Finleydale());
// ...
registry = Collections.unmodifiablemap(_registry);
}
public static Location getLocation(final String id)
{
return registry.get(id);
}
}
Some notes:
You could still use the Singleton pattern to populate the registry
The classic Singleton pattern, as demonstrated in your question, is not thread-safe. A correctly thread-safe version without unnecessary locking is very tricky, if not impossible. A static final field resolves that problem nicely.
It isn't necessary to have the registry explicitly reference each Location subclass. You could have each location register itself. The only trick is to have a mechanism that would load the locations so that they can register themselves.
Are subclasses actually suitable for this use? Do different locations have different behaviors or just different data (ie name)? If the latter, then I would just use a single Location class and a single factory, such as the static initializer above, to create each location.

Something about your object model seems wrong. Why not have an interface Locatable with a getLocation() method on it, and implementers of the interface can return their respective locations. A singleton Location just seems conceptually wrong.
interface Locatable {
Location getLocation();
}
class FinleyLand implements Locatable {
#Override
Location getLocation() {
//whatever it takes to get you there...
}
}

I took the get() function's static modifier away and changed the Player class as shown. All you other guys, your input was great.
String locationS; //Class name
public static Location getLocation() {
return ((Location) Class.forName(locationS).newInstance()).get();
}

Related

Static to non-static refactoring, can't have both?

I have a refactoring situation that I cannot find an elegant solution for...
Disclaimer:
Keep in mind that I am oversimplifying this example to reduce clutter, and not disclose things I am not allowed to disclose :)
As such, please do not assume that this is the ONLY code in my giant codebase, and offer solutions that cut corners or change parts of the design that I mention cannot be changed due to outside constraints.
The facts:
I have a utility class, it has a bunch of static methods, they utilize a singleton resource:
public final class Utility
{
private static final Resource RES = Resource.getInstance();
private Utility() {} // Prevent instantiating Utility
public static boolean utilMethodOne() { return RES.isSomething(); }
public static int utilMethodTwo() { RES.getNumThings(); }
...
public static void utilMethodInfinity() { ... }
}
Utility is in a library JAR that is used by several applications in a large codebase -- let's say on the order of 10,000 calls to its static methods, e.g.: if(Utility.utilMethodOne()) { ... }
Resource is an outside class from another library JAR.
Resource also has a method Resource.getInstance(String name) that will return a named instance, which may relate to a different underlying resource based on the name (internally it keeps the named resources in a Map<String,Resource>).
Resource.getInstance() returns the equivalent of Resoruce.getInstance(""), aka the default instance.
The situation:
The Utility needs to be enhanced to now execute against one of several resources, so my plan is to make the Utility an instantiable class with a non-static Resource member variable. Something like this:
public final class Utility
{
private Resource res;
public Utility(String resName)
{
this.res = = Resource.getInstance(resName);
}
public boolean utilMethodOne() { return this.res.isSomething(); }
public int utilMethodTwo() { this.res.getNumThings(); }
...
public void utilMethodInfinity() { ... }
}
Now all this is great, and I can start creating Utility objects that access their specified resource instead of just the default one. However, as I mentioned, there are 10-100K method calls that are now invalid as they were calling static methods!
The problem:
My plan was to keep the static methods in Utility, and have them use the default instance from Resource, while adding in non-static variants for the instantiated Utility objects that use their "local" resource reference.
// Best of both worlds:
public static boolean utilMethodOne() { return RES.isSomething(); }
public boolean utilMethodOne() { return this.res.isSomething(); }
Maybe I can't have my cake & eat it too:
error: method utilMethodOne() is already defined in class Utility
public static boolean utilMethodOne(String sql)
So it seems I am going to have to either...
Introduce a whole new BetterUtility class for places that want to use the named-resources.
Update 10,000 places to instantiate & use the revised Utility object.
...? (hint: this is where your suggestions come in!)
I really don't like 1 or 2 for a variety of reasons, so I need to ensure there is no better 3 option before settling. Is there any way to retain a single class that can provide both the static & non-static interfaces in this case?
UPDATE 2020-06-01:
I am coming to the realization that this magical option 3 doesn't exist. So out of my original two options I think #2 is best as it's just one time "just get it out of the way and be done with it" type effort. Also incorporated some of your suggestions in the design(s).
So now that I have a direction on this, I am left with [hopefully only] one more key decision...
Update all the calls to create new objects
// For a one-off call, do it inline
boolean foo = new Utility("res1").utilMethodOne();
// Or when used multiple times, re-use the object
Utility util = new Utility("res1");
boolean foo = util.utilMethodOne();
int bar = util.utilMethodTwo();
...
Given the amount/frequency of usage, this seems like a whole lot of wasted efforts creating short-lived objects.
Follow the pattern that Resource itself uses, creating my own named-singleton map of Utilities (1:1 with their respectively named Resource)
public final class Utility
{
private static final Map<String,Utility> NAMED_INSTANCES = new HashMap<>();
private Resource res;
private Utility(String resName)
{
this.res = Resource.getInstance(resName);
}
public static Utility getInstance(String resName)
{
synchronized(NAMED_INSTANCES)
{
Utility instance = NAMED_INSTANCES.get(resName);
if(instance == null)
{
instance = new Utility(resName);
NAMED_INSTANCES.put(resName, instance);
}
return instance;
}
}
public boolean utilMethodOne() { return this.res.isSomething(); }
public int utilMethodTwo() { this.res.getNumThings(); }
...
public void utilMethodInfinity() { ... }
}
// Now the calls can use
Utility.getInstance("res1")
// In place of
new Utility("res1")
So essentially this boils down to object creation vs. a synchronization + map lookup at each usage. Probably a little bit of premature optimization here, but I'll probably have to stick with this decision long term.
UPDATE 2020-06-29:
Didn't want to leave an "Internet dead end" here...
I did eventually get all the call sites updated as described above (including option #2 from the 2020-06-01 update). It has made it through all testing and been running in production for a week or so now in various applications.
It seems that you may want to turn the Utility into a singleton map that will have the same static methods that access the singleton without any arguments on for the function invocations (just like you have now)
The singleton will support a static method of adding a new resource, you will then add it to the map.
In addition you can overload the existing methods to also accept an argument resource name, that will then use a particular resource from the map, otherwise will use the default entry from the map.
Keep the old methods and the new methods static.
private static final String DEFAULT = "RESOURCE1";
private static Map<String, Resource> resources = new HashMap();
static{
// initialize all resources
}
public static boolean utilMethod() { return resources.get(DEFAULT).isSomething(); }
public static boolean utilMethod(String resourceName) { return resources.get(resourceName).isSomething(); }

Instantiate public object inside method

I'm trying to instantiate an object inside a method of a class so it can be used anywhere in the class. I come from a python background and it is quite easy, you can just pass the instantiated object to an instance of it's "self" like below.
self.camera = CameraInstance()
How do you do this in Java? I tried something like below but it doesn't like it.
private void init_camera_settings() {
public CameraInterface camera;
camera.TakePhoto()
}
private void someotherMethod() {
camera.TakePhoto()
}
Both methods are in the same class. The reason for this is because I only want to instantiate the camera object only in certain scenarios.
Thanks!
You can't declare a field inside a method. In Java, a type either has a field, or it doesn't. Every instance of the same class has the same set of fields.
But you can declare the field (not in a method) and decide to only assign a value to it in a method:
// Note: avoid public fields
public CameraInterface camera;
private void initCameraSettings() {
camera = new Camera();
}
private void someotherMethod() {
camera.takePhoto();
}
(The field will have a default value, in this case null, until you assign a different value to it.)
As an aside, I'd strongly advise against public fields. I make every field private, and add properties to allow access where necessary. This allows you to change implementation details later. The one exception to this is public static final fields of immutable types, basically for constants, but even there I'd be cautious.
To use the variable throughout the class in different methodsm the variables should have class scope. You usually use new to create a new Object
public MyClass {
public CameraInterface camera = new Camera ();
private void init_camera_settings() {
camera.TakePhoto()
}
private void someotherMethod() {
camera.TakePhoto()
}
}
self.camera = CameraInstance()
is equivalent to:
class Foo {
private CameraInstance camera;
public Foo() {
this.camera = new CameraInstance();
}
// use "this.camera" in methods.
}

Using object reference to get methods from another class

So I have a concrete class and an abstract class and I am trying to access methods from the concrete class from the abstract one. Store currently contains many getters that the member class needs. Currently get null pointer exception.
public abstract class members{
// Trying to refrence the store object
Store store;
public void someMethod(){
// I want to be able to access all the methods from the store class
// eg
store.showVideoCollection();
}
}
public class store {
// This class has already been instantiated, just one object for it.
public void showVideoCollection(){
// Stuff here
}
public void otherMethod(){
// Stuff here
}
}
EDIT:
In the main method
public class start {
public start() {
store = new Store(); // Don't want to create more than 1 store object.
}
Thanks
In order to store a Store instance you must instantiate it. As is, you declare the variable store but you never initialize it (so it's null). I think you wanted something like
// Trying to refrence the store object
Store store = new Store(); // <-- create a Store and assign it to store.
Alternatively, you could make Store a Singleton. The linked Wikipedia page says (in part) the singleton pattern is a design pattern that restricts the instantiation of a class to one object.
public final class Store {
public static Store getInstance() {
return _instance;
}
private static final Store _instance = new Store();
private Store() {
}
public void showVideoCollection(){
// Stuff here
}
public void otherMethod(){
// Stuff here
}
}

How to use Java Enums being DRY with only a single parameter different between instantiations?

I'm trying to figure out if there is a clean way of doing this. I want to design an ENUM to maintain a list of constant values for different components in my application. Each enum would have the same configuration and same parameters, but would differ at the very least by component name.
In a normal Java class, I could build all the basic logic/code in a base abstract class, and have each component constants extend the abstract class and populate only its own pertinent information. However, Java enums do not allow extending existing classes.
Is there something I can do to avoid having to either push all my constants in a single Enum (ugggg!) or recreate the same enum class each time for each differing component? Definitely not DRY in that case, but I do not know how to avoid the issue.
For a quick use-case example off the top of my head. Say I want to keep a list of all my request mappings in an Enum for use elsewhere in my application. Fairly easy to design an enum that says:
public enum RequestMapping {
INDEX("index"),
GET_ALL_USERS( "getAllUsers");
private String requestMapping = "/users";
private String path;
RatesURI( String path ){
this.path = path;
}
public String getRequestMapping(){
return requestMapping;
}
public String getPath(){
return path;
}
public String getFullRequestPath(){
return requestMapping + "/" + path;
}
}
It becomes easy to use RequestMapping.GET_ALL_USERS.getFullRequestPath().
Now if I want to create this enum on a per-controller basis, I would have to recreate the entire Enum class and change the "requestMapping" value for each one. Granted, this enum has nearly no code in it, so duplicating it would not be difficult, but the concept still remains. The theoretical "clean" way of doing this would be to have an abstract AbstractRequestMapping type that contained all the methods, including an abstract getRequestMapping() method, and only have the extending Enums implement the controller-specific getReqeuestMapping(). Of course, since Enums cannot be extended, I can't think of a non DRY way of doing this.
Have you considered extending a class that takes Enum as a generic parameter? It is an amazingly flexible mechanism.
public class Entity<E extends Enum<E> & Entity.IE> {
// Set of all possible entries.
// Backed by an EnumSet so we have all the efficiency implied along with a defined order.
private final Set<E> all;
public Entity(Class<E> e) {
// Make a set of them.
this.all = Collections.unmodifiableSet(EnumSet.<E>allOf(e));
}
// Demonstration.
public E[] values() {
// Make a new one every time - like Enum.values.
E[] values = makeTArray(all.size());
int i = 0;
for (E it : all) {
values[i++] = it;
}
return values;
}
// Trick to make a T[] of any length.
// Do not pass any parameter for `dummy`.
// public because this is potentially re-useable.
public static <T> T[] makeTArray(int length, T... dummy) {
return Arrays.copyOf(dummy, length);
}
// Example interface to implement.
public interface IE {
#Override
public String toString();
}
}
class Thing extends Entity<Thing.Stuff> {
public Thing() {
super(Stuff.class);
}
enum Stuff implements Entity.IE {
One,
Two;
}
}
You can pass the nature of your implementation up to the parent class in many different ways - I use enum.class for simplicity.
You can even make the enum implement an interface as you can see.
The values method is for demonstration only. Once you have access to the Set<E> in the parent class you can provide all sorts of functionality just by extending Entity.
I will probably split the responsibilities into two parts:
Logic about how a request is structured, and put that into an immutable class.
Actual configurations of each request, stored in enums
The enum will then store an instance of that class, you can add new methods to the class, without modifying the different enums, as long as the constructor remains the same. Note that the class must be immutable, or your enum will not have a constant value.
You can use it like the:
ServiceRequest.INDEX.getRequest().getFullRequestPath()
With these classes:
public interface RequestType {
Request getRequest();
}
public class Request {
private final String requestMapping;
private final String path;
RatesURI(String requestMapping, String path){
this.requestMappint = requestMapping;
this.path = path;
}
public String getRequestMapping(){
return requestMapping;
}
public String getPath(){
return path;
}
public String getFullRequestPath(){
return requestMapping + "/" + path;
}
}
public enum ServiceRequest implements RequestType {
INDEX("index"),
GET_ALL_USERS( "getAllUsers");
private final Request;
ServiceRequest(String path) {
request = new Request("users/", path)
}
public String getRequest{
return request;
}
}
I think what you should be asking yourself is really why you want to use enums for this. First we can review some of the points that make Java enumerated types what they are.
Specifically
A Java enum is a class that extends java.lang.Enum.
Enum constants are static final instances of that class.
There is some special syntax to use them but that is all they boil down to. Because instantiating new Enum instances is disallowed outside of the special syntax (even with reflection, enum types return zero constructors) the following is also ensured to be true:
They can only be instantiated as static final members of the enclosing class.
The instances are therefore explicitly constant.
As a bonus, they are switchable.
What it really boils down to is what it is about the enums that makes them preferable over a simpler OOP design here. One can easily create a simple RequestMapping class:
/* compacted to save space */
public class RequestMapping {
private final String mapping, path;
public RequestMapping(String mapping, String path) {
this.mapping = mapping; this.path = path;
}
public String getMapping() {
return mapping; }
public String getPath() {
return path; }
public String getFullRequestPath() {
return mapping + "/" + path;
}
}
Which can easily be extended to break down the repeated code:
public class UserMapping extends RequestMapping {
public UserMapping(String path) {
super("/users", path);
}
}
/* where ever appropriate for the constants to appear */
public static final RequestMapping INDEX = new UserMapping("index"),
GET_ALL_USERS = new UserMapping("getAllUsers");
But I assume there is something about enums that is attractive to your design, such as the principle that instances of them are highly controlled. Enums cannot be created all willy-nilly like the above class can be. Perhaps it's important that there be no plausible way for spurious instances to be created. Of course anybody can come by and write in an enum with an invalid path but you can be pretty sure nobody will do it "by accident".
Following the Java "static instances of the outer class" enum design, an access modifier structure can be devised that generally abides by the same rule set as Enum. There are, however, two problems which we can't get around easily.
Two Problems
Protected modifier allows package access.
This can easily be surmounted initially by putting the Enum-analog in its own package. The problem becomes what to do when extending. Classes in the same package of the extended class will be able to access constructors again potentially anywhere.
Working with this depends on how stringent you want to be on creating new instances and, conversely, how clear the design ends up. Can't be a whole mess of scopes just so only a few places can do the wrong thing.
Static members are not polymorphic.
Enum surmounts this by not being extendable. Enum types have a static method values that appears "inherited" because the compiler inserts it for you. Being polymorphic, DRY and having some static features means you need instances of the subtype.
Defeating these two issues depends on how stringent you want your design to be and, conversely, how readable and stable you want your implementation to be. Trying to defy OOP principles will get you a design that's hard to break but totally explodes when you call that one method in a way you aren't supposed to (and can't prevent).
First Solution
This is almost identical to the Java enum model but can be extended:
/* 'M' is for 'Mapping' */
public abstract class ReturnMapping<M extends ReturnMapping> {
/* ridiculously long HashMap typing */
private static final HashMap <Class<? extends ReturnMapping>, List<ReturnMapping>>
VALUES = new HashMap<Class<? extends ReturnMapping>, List<ReturnMapping>>();
private final String mapping, path;
protected Mapping(String mapping, String path) {
this.mapping = mapping;
this.path = path;
List vals = VALUES.get(getClass());
if (vals == null) {
vals = new ArrayList<M>(2);
VALUES.put(getClass(), vals);
}
vals.add(this);
}
/* ~~ field getters here, make them final ~~ */
protected static <M extends ReturnMapping> List<M>(Class<M> rm) {
if (rm == ReturnMapping.class) {
throw new IllegalArgumentException(
"ReturnMapping.class is abstract");
}
List<M> vals = (List<M>)VALUES.get(rm);
if (vals == null) {
vals = new ArrayList<M>(2);
VALUES.put(rm, (List)vals);
}
return Collections.unmodifiableList(vals);
}
}
Now extending it:
public final class UserMapping extends ReturnMapping<UserMapping> {
public static final UserMapping INDEX = new UserMapping("index");
public static final UserMapping GET_ALL_USERS = new UserMapping("getAllUsers");
private UserMapping(String path) {
super("/users", path);
}
public static List<UserMapping> values() {
return values(UserMapping.class);
}
}
The huge static HashMap allows almost all of the values work to be done statically in the superclass. Since static members are not properly inherited this is the closest you can get to maintaining a list of values without doing it in the subclass.
Note there are two problems with the Map. The first is that you can call the values with ReturnMapping.class. The map should not contain that key (the class is abstract and the map is only added to in the constructor) so something needs to be done about it. Instead of throwing an exception you could also insert a "dummy" empty list for that key.
The other problem is that you can call values on the superclass before the instances of the subclass are instantiated. The HashMap will return null if this is done before the subclass is accessed. Static problem!
There is one other major problem with this design because the class can be instantiated externally. If it's a nested class, the outer class has private access. You can also extend it and make the constructor public. That leads to design #2.
Second Solution
In this model the constants are an inner class and the outer class is a factory for retrieving new constants.
/* no more generics--the constants are all the same type */
public abstract class ReturnMapping {
/* still need this HashMap if we want to manage our values in the super */
private static final HashMap <Class<? extends ReturnMapping>, List<Value>>
VALUES = new HashMap<Class<? extends ReturnMapping>, List<Value>>();
public ReturnMapping() {
if (!VALUES.containsKey(getClass())) {
VALUES.put(getClass(), new ArrayList<Value>(2));
}
}
public final List<Value> values() {
return Collections.unmodifiableList(VALUES.get(getClass()));
}
protected final Value newValue(String mapping, String path) {
return new Value(getClass(), mapping, path);
}
public final class Value {
private final String mapping, path;
private Value(
Class type,
String mapping,
String path) {
this.mapping = mapping;
this.path = path;
VALUES.get(type).add(this);
}
/* ~~ final class, field getters need not be ~~ */
}
}
Extending it:
public class UserMapping extends ReturnMapping {
public static final Value INDEX, GET_ALL_USERS;
static {
UserMapping factory = new UserMapping();
INDEX = factory.newValue("/users", "index");
GET_ALL_USERS = factory.newValue("/users", "getAllUsers");
}
}
The factory model is nice because it solves two problems:
Instances can only be created from within the extending class.
Anybody can create a new factory but only the class itself can access the newValue method. The constructor for Value is private so new constants can only be created by using this method.
new UserMapping().values() forces the values to be instantiated before returning them.
No more potential errors in this regard. And the ReturnMapping class is empty and instantiating new objects in Java is fast so I wouldn't worry about overhead. You can also easily create a static field for the list or add static methods such as in solution #1 (though this would deflate the design's uniformity).
There are a couple of downsides:
Can't return the subtyped values List.
Now that the constant values are not extended they are all the same class. Can't dip in to generics to return differently-typed Lists.
Can't easily distinguish what subtype a Value is a constant of.
But it's true this could be programmed in. You could add the owning class as a field. Still shaky.
Sum Of It
Bells and whistles can be added to both of these solutions, for example overriding toString so it returns the name of the instance. Java's enum does that for you but one of the first things I personally do is override this behavior so it returns something more meaningful (and formatted).
Both of these designs provide more encapsulation than a regular abstract class and most importantly are far more flexible than Enum. Trying to use Enum for polymorphism is an OOP square peg in a round hole. Less polymorphism is the price to pay for having enumerated types in Java.

Java - Class type from inside static initialization block

Is it possible to get the class type from inside the static initialization block?
This is a simplified version of what I currently have::
class Person extends SuperClass {
String firstName;
static{
// This function is on the "SuperClass":
// I'd for this function to be able to get "Person.class" without me
// having to explicitly type it in but "this.class" does not work in
// a static context.
doSomeReflectionStuff(Person.class); // IN "SuperClass"
}
}
This is closer to what I am doing, which is to initialize a data structure that holds information about the object and its annotations, etc... Perhaps I am using the wrong pattern?
public abstract SuperClass{
static void doSomeReflectionStuff( Class<?> classType, List<FieldData> fieldDataList ){
Field[] fields = classType.getDeclaredFields();
for( Field field : fields ){
// Initialize fieldDataList
}
}
}
public abstract class Person {
#SomeAnnotation
String firstName;
// Holds information on each of the fields, I used a Map<String, FieldData>
// in my actual implementation to map strings to the field information, but that
// seemed a little wordy for this example
static List<FieldData> fieldDataList = new List<FieldData>();
static{
// Again, it seems dangerous to have to type in the "Person.class"
// (or Address.class, PhoneNumber.class, etc...) every time.
// Ideally, I'd liken to eliminate all this code from the Sub class
// since now I have to copy and paste it into each Sub class.
doSomeReflectionStuff(Person.class, fieldDataList);
}
}
Edit
I picked the accepted answer based on what applied best to my problem, however it seems to me that all three of the current answers have their merits.
No, it's not possible without grabbing the stacktrace (which is imo nastier than your initial approach and for which I would in any way prefer Thread#getStackTrace() above new Exception()).
Rather do that job in a non-static initializer (or the default constructor) of the abstract class where you check the initialized status.
public abstract class SuperClass {
{
if (!isInitialized(getClass())) {
initialize(getClass());
}
}
}
The called methods in turn can be safely static.
yes, I use this often to initialize a static Log variable :
e.g. :
public class Project implements Serializable, Cloneable, Comparable<Project> {
private static final Logger LOG = LoggerFactory.getLogger(Project.class);
...
To get a class at runtime, you could do something along the lines of
public class Test {
public static void main(String[] args) {
try{
throw new Exception();
}
catch(Exception e){
StackTraceElement[] sTrace = e.getStackTrace();
// sTrace[0] will be always there
String className = sTrace[0].getClassName();
System.out.println(className);
}
}
}
Not pretty but will do the job (ripped from http://www.artima.com/forums/flat.jsp?forum=1&thread=155230).
This means you still make a call from the subclass (so is in the stack trace), but you don't need to include the XXX.class as an argument.

Categories

Resources