Java - Fields vs implemented Methods - java

I have to parse a JSON response and return objects which holds its data. But I am not sure which solution is more "memory-friendly":
Method 1: Fields
public class MyElement {
private int var1;
public MyElement(int var1) {
this.var1 = var1;
}
public int getVar1() {
return var1;
}
}
Method 1.1: Direct access on field.
Method 1.2: Using builders/factories.
Method 2:
public interface MyElement {
int getVar1();
}
// In Code
return new MyElement() {
#Override
public int getVar1() {
return 5;
}
}

Side note: public getVar1() does not compile. Any difference between methods 1, 1.1 and 1.2 is negligible (though 1.1 is mutable unless you make your field final), but I would use method 1. This is because, with method 2, a new (anonymous) class is actually created. If this is executed many times, tons of classes are created. Of course, such differences usually wouldn't matter unless on a truly massive scale, so don't make memory an issue when it isn't one.

I think the Java Bean Standard is a better approach as it followed in most of the implementations in software development.
I have good references links for you below which will explain details about your doubts :
Places where JavaBeans are used?
When would you use the Builder Pattern?

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(); }

Call method on template argument without knowing a base class in Java

I would like to write a generic algorithm, which can be instantiated with different objects. The objects are coming from 3rdparty and they have no common base class. In C++, I just write the generic algorithm as a template which takes the particular object as its argument. How to do it in Java?
template <class T>
class Algorithm
{
void Run(T& worker)
{
...
auto value = workder.DoSomething(someArgs);
...
}
};
In C++, I don't need to know anything about the T, because the proper types and availability of methods are checked during compilation. As far as I know,
in Java I must have a common base class for all my workers to be able to call methods on them. Is it right? Is there a way how to do similar stuff in Java?
I can't change my 3rdparty workers, and I don't want to make my own abstraction of all workers (including all types which the workers are using, etc.).
Edit:
Since I want to write the generic algorithm only once, maybe it could be a job for some templating language which is able to generate Java code (the arguments to the code template would be the workers)?
My solution:
In my situation, where I cannot change the 3rdparty workers, I have chosen Java code generation. I have exactly the same algorithm, I only need to support different workers which all provides identical interface (classes with same names, same names of methods, etc.). And in few cases, I have to do a small extra code for particular workers.
To make it more clear, my "workers" are in fact access layers to a proprietary DB, each worker for a single DB version (and they are generated).
My current plan is to use something like FreeMaker to generate multiple Java source files, one for each DB version, which will have only different imports.
The topic to look into for you: generics
You can declare a class like
public class Whatever<T> {
which uses a T that allows for any reference type. You don't need to further "specialize" that T mandatorily. But of course: in this case you can only call methods from Object on instances of T.
If you want to call a more specific method, then there is no other way but somehow describing that specification. So in your case, the reasonable approach would be to introduce at least some core interfaces.
In other words: there is no "duck typing" in Java. You can't describe an object by only saying it has this or that method. You always need a type - and that must be either a class or an interface.
Duck typing isn't supported in Java. It can be approximated but you won't get the convenience or power you're used to in C++.
As options, consider:
Full-on reflection + working with Object - syntax will be terrible and the compiler won't help you with compilation checks.
Support a pre-known set of types and use some sort of static dispatching, e.g a big switch / if-else-if block, a type -> code map, etc. New types will force changing this code.
Code generation done during annotation processing - you may be able to automate the above static-dispatch approach, or be able to create a wrapper type to each supported type that does implement a common interface. The types need to be known during compilation, new types require recompilation.
EDIT - resources for code generation and annotation processing:
Annotation processing tutorial by #sockeqwe
JavaPoet, a clean code generation tool by Square
If you really don't have any way to get it done correctly with generics you may need to use reflection.
class A {
public String doIt() {
return "Done it!";
}
}
class B {
public Date doIt() {
return Calendar.getInstance().getTime();
}
}
interface I {
public Object doIt();
}
class IAdapter implements I {
private final Object it;
public IAdapter(Object it) {
this.it = it;
}
#Override
public Object doIt() {
// What class it it.
Class<?> itsClass = it.getClass();
// Peek at it's methods.
for (Method m : itsClass.getMethods()) {
// Correct method name.
if (m.getName().equals("doIt")) {
// Expose the method.
m.setAccessible(true);
try {
// Call it.
return m.invoke(it);
} catch (Exception e) {
throw new RuntimeException("`doIt` method invocation failed", e);
}
}
}
// No method of that name found.
throw new RuntimeException("Object does not have a `doIt` method");
}
}
public void test() throws Exception {
System.out.println("Hello world!");
Object a = new IAdapter(new A()).doIt();
Object b = new IAdapter(new B()).doIt();
System.out.println("a = "+a+" b = "+b);
}
You should, however, make every effort to solve this issue using normal type-safe Java such as Generics before using reflection.
In Java all your Workers must have a method DoSomething(someArgs), which doesn't necessarily imply that they extend the same base class, they could instead implement an interface Worker with such a method. For instance:
public interface Worker {
public Double DoSomething(String arg1, String arg2);
}
and then have different classes implement the Worker interface:
One implementation of Worker:
public class WorkerImplA implements Worker{
#Override
public Double DoSomething(String arg1, String arg2) {
return null; // do something and return meaningful outcome
}
}
Another implementatin of Worker:
public class WorkerImplB implements Worker{
#Override
public Double DoSomething(String arg1, String arg2) {
return null; // do something and return meaningful outcome
}
}
The different WorkerImpl classes do not need to extend the same common base class with this approach, and as of JavaSE 8 interfaces can have a default implementation in any method they define.
Using this approach Algorithm class would look like:
public class Algorithm {
private String arg1;
private String arg2;
public Algorithm(String arg1, String arg2){
this.arg1 = arg1;
this.arg2 = arg2;
}
public void Run(Worker worker){
worker.DoSomething(arg1, arg2);
}
}

Using enums in an object-orientated way when they apply to many classes

So, I here was my previous code:
public enum eDay {
eMON,
eTUE,
eWED
}
eDay day = eMON;
switch( day ) {
case eMON:
//load class 1
break;
case eTUE:
//load class 2
break;
case eWED:
//load class 3
break;
}
Reading around, the OO way to do things is to have an enum that overrides a method rather than using a switch statement, such as:
enum eDay {
eMON {
#Override
public void loadClass() {
//load class 1
}
},
eTUE {
#Override
public void loadClass() {
//load class 2
}
};
public abstract void loadClass();
}
void aMethodSomewhere(final eDay e) {
e.loadClass();
}
While the concept of using polymorphism makes sense to me, rather than using a switch statement, what happens in the situation where the enum is used in different classes to do different things? For example, different classes behave differently according to a limited set of options, defined in the enum ( so not always performing loadClass() ).
Should you define different methods according to the different classes? To my mind, that would increase object coupling greatly.
I would really like to do OO properly, so good advice is much appreciated.
Many thanks.
In general, you want to use polymorphism to avoid if() blocks and for behavior reuse, you should favor composition.
In your case, I understand that there is some dynamic behavior involved in your design and, therefore, the use of enums could not be advisable.
Enums have a lot of advantages: they're final, static and every instance is a singleton by default. Whenever I need a static singleton that is up when the JVM starts, I favor enums over classes.
In this case, if you have some dynamic behavior going on, you could write a class with some static final properties that are an instance of the same class. With proper visibility modifiers for constructors or factory methods, the external API of the class could be the same as with the enum.
In order to inject the dynamic behavior, you could use Strategy design pattern or even inject a Function (if you're using Java8) as a parameter in the class' constructor.
public static class eDays {
public static final eDay eMON = new eDay(i -> i + 1);
public static final eDay eTUE = new eDay(i -> i + 2);
public static class eDay {
private final Function<Integer, Integer> loadClassStrategy;
public eDay(Function<Integer, Integer> loadClassStrategy) {
this.loadClassStrategy = loadClassStrategy;
}
public int loadClass(int i) {
return loadClassStrategy.apply(i);
}
}
}
void aMethodSomewhere(final eDays.eDay e) {
e.loadClass(1);
}
// or even...
void aMethodSomewhere() {
eDay eMON = new eDay(i -> i + 1);
eMON.loadClass(1);
}
If your behavior is not dynamic, you could continue using enums, but you could inject the behavior in their constructor to improve readability:
public enum eDay {
eMON(i->i+1),
eTUE(i->i+2);
private final Function<Integer, Integer> loadClassStrategy;
eDay(Function<Integer, Integer> loadClassStrategy) {
this.loadClassStrategy = loadClassStrategy;
}
public int loadClass(int i) {
return loadClassStrategy.apply(i);
}
}
void aMethodSomewhere(eDay e) {
e.loadClass(1);
}
I'd advise against putting this kind of behavior in enums; that's really not what they are designed for*. Instead, it might be better to maintain a map of enums and handlers.
Map<Eday, Loader> enumHandlerMap = new EnumMap<>();
Loader should be an interface (basically the stuff you had in your enum):
public interface Loader {
void loadClass();
}
Then you can initialize your your handler map like so:
enumHanderMap.put(EDay.MON, new Loader() {
#Override
public void loadClass() {
...
}
});
And you can run a handler like so:
enumHandler.get(eDayEnum).loadClass();
*To clarify, the semantic conveyed by enums is that you are dealing with a static, predefined set of values. I think an acceptable form of logic to include within enums is the kind that provides additional information about each of the values. The Planet enum is a good example because it provides additional information related to each enum. There is no strict rule to define what is "too much" logic. But if you find yourself implementing a method on an enum that talks to a database, or makes an HTTP connection, I would argue that you're doing too much. In general, the logic you implement inside the enum shouldn't concern itself with other parts of your model or business logic; it shouldn't need access to additional entities from your model, or other services. If you can convey additional information and behavior in the context of the enum itself, then you might be alright. But if you are using the enum to implement complex behavior that involves other entities or services, then the enum is doing too much.
Enum in Java is used for the non-changeable and defined constants.
It seems to me that you would like to have differently behaived classes based on some conditions. If so the strategy patter would be more suitable for this task.
For more info click here.

Can a non-changing enum method be optimized by the JVM at runtime?

Can the JVM perform runtime optimization in the following scenario?
We've got the following situation, we have this interface:
public interface ECSResource {
default int getFor(final Entity entity) {
return ResourceRetriever.forResource(this).getFor(entity);
}
}
And a concrete implementation such as:
private static enum TestResources implements ECSResource {
TR1, TR2;
}
Would the JVM be able to figure out (at runtime) that an enum instance such as TestResources.TR1 belongs to a single ResourceRetriever like ResourceRetriever.forResource(TestResources.TR1)?
In the naive implementation every call to TestResources.TR1.getFor(...) would create a new ResourceRetriever instance.
In this case though, we know that (by code inspection) a call to ResourceRetriever.forResource(this) will call the following:
public class ResourceRetriever {
private final ECSResource resource;
ResourceRetriever(ECSResource resource) {
this.resource = resource;
}
public static ResourceRetriever forResource(ECSResource resource) {
return new ResourceRetriever(resource);
}
//lots of methods
}
Hence there is nothing that can change at runtime due to random results, rounding errors, etc.
Hence the question: Can the JVM map every enum ECSResource instance to its unique corresponding ResourceRetriever.forResource(this) instance?
Note that it is possible to do such thing by your own, via the following:
private static enum TestResources implements ECSResource {
TR1, TR2;
private static final Map<TestResources, ResourceRetriever> retrieverMapping;
static {
retrieverMapping = Arrays.stream(TestResources.values())
.collect(Collectors.toMap(res -> res, ResourceRetriever::forResource));
}
#Override
public int getFor(final Entity entity) {
return retrieverMapping.get(this).getFor(entity);
}
}
The semantics of the new keyword almost certainly prohibit what you're wanting to do. (See references both in The Java Language Specification and The Java Virtual Machine Specification.) Your forResource method is always going to return a new object. I don't know of any JVMs that would do what you're trying to do, given that there is no mechanism to determine that only one ResourceRetriever should be created for any given ECSResource. This looks like a form of memoization to me, which would be handled by the language (e.g. Groovy, which has an annotation specifically for this) and not by the runtime (JVM). If Java had reified generics, you could possibly hack such a feature with something like ResourceRetriever<? extends ECSResource> but I can't say whether that would actually work, much less whether it would be a good idea or not.

How can we add transient to existing class using reflection in java?

Is there any way to make field static or transient using java reflection API.
EDIT: I have some Beans that are already being serialised using soap api and is being used by some clients, for some clients i don't want to expose one or two fields.
Sure there are so many ways to do it without changing or adding transient keyword.
Just want to know if it can be done, and if so, how ?
EDIT: I wouldn't call it an API or framework issue, more like a design flaw...
I'm using apache axis2 for soap
No. Such a thing would require modifying the byte code of the class. A particular difficulty in the case of static fields is that they are accessed using different bytecodes than object fields.
I don't see a why a field couldn't be made transient in runtime, at least in theory, but the current reflection API doesn't allow it. See also: Can a field's transient property/flag be set through reflection in java?
You can't do it with the reflection api. I think there are some byte-code manipulation tools but in this case you can use the Decorator pattern. It solves the problem but I think it is extremely ugly:
(I omited the usual boilerplate from here such as interfaces)
public class StaticDecorator {
private static Object staticField;
private Object yourObject;
public StaticDecorator(Object yourObject) {
this.yourObject = yourObject;
}
public static Object getStaticField() {
return staticField;
}
public static void setStaticField(Object object) {
staticField = object;
}
}
I used Object for the type of the class you are going to wrap but of course you can substitute any type you want. Using an approach like this you can "decorate" any class with a static field.
If you are really, extremely must want a static field in an object at run time this can help you but I think that there is a design flaw lurking somewhere.
You can wrap your bean inside another bean that only exposes the fields that you'd like to expose through your API. For example, with an internal bean with the fields foo, bar, and baz, where you do not want to expose baz.
Lombok Delegation can make this incredibly simple, but here's an example using plain-old-Java.
public class ExposedBean {
private InternalBean internalBean;
public ExposedBean(InternalBean internalBean) {
this.internalBean = internalBean;
}
public String getFoo() { return internalBean.getFoo(); }
public String getBar() { return internalBean.getBar(); }
}
public class InternalBean {
private String foo;
private String bar;
private String baz;
public String getFoo() { return foo; }
public String getBar() { return bar; }
public String getBaz() { return baz; }
}
Original answer, regarding setting modifiers
You can not set modifiers. You can check them, however.
Field myField = /* get a field object */;
if (Modifier.isTransient(myField.getModifiers()) {
System.out.println("myField is transient.");
}
if (Modifier.isFinal(MyClass.class.getModifiers()) {
System.out.println("MyClass is final.");
}
With more information about the problem you're trying to solve, we can suggest alternatives. Member#getModifiers() is not declared final, so you could possibly use a decorator. (The below code is 100% untested.)
public class FieldModifierDecorator extends Field {
protected Field field;
private int modifiers = -1;
public static void decorate(Field field) {
FieldModifierDecorator newInstance = new FieldModifierDecorator();
newInstance.field = field;
return newInstance;
}
public void overrideModifiers(int modifiers) {
this.modifiers = modifiers;
}
public int getModifiers() {
if (-1 == modifiers) {
return field.getModifiers();
}
return modifiers;
}
}
// Example usage
public Field makeFieldAppearTransient(Field field) {
FieldModifierDecorator decoratedField = FieldModifierDecorator.decorate(field);
decoratedField.overrideModifiers(field.getModifiers() | Modifier.TRANSIENT);
// if (Modifier.isTransient(decoratedField.getModifiers())) {
// System.out.println("It looks transient, but really isn't.");
//}
return decoratedField;
}
Modfifying class information or byte code modification is definitely the wrong tool for the job. You are trying to solve a business problem with solely technical tools.
It sounds more like you need a permission concept. Users may have permission to see some fields. Based on that you could use java bean introspection to clear the values of those fields just before they are sent to the client.
However this might have its problems as well. A client should be able to determine if it has permission to see that field or not.

Categories

Resources