How the enum that we get from java 1.5 is different from C++ and other conventional Enum Type.
In java enums are complex objects, whilst in C++ every enum object is associated with a single integer value. In java you can have several attributes associated with a single enum value:
enum MyCategory {
SPORT("The sport category", "sport.png"),
NEWS("the news category", "news.jpg");
private String description;
private String iconPath;
private MyCategory(String description, String iconPath) {
this.description = description;
this.iconPath = iconPath;
}
public String getDescription() {
return description;
}
public String getIconPath() {
return iconPath;
}
}
Furthermore in java you can switch only Number types, Strings and enums. However I can not generalize the conventional enums as a whole...
EDIT One more thing the java enums can do is declare per-value operation (taken from the java tutorial):
public enum Operation {
PLUS { double eval(double x, double y) { return x + y; } },
MINUS { double eval(double x, double y) { return x - y; } },
TIMES { double eval(double x, double y) { return x * y; } },
DIVIDE { double eval(double x, double y) { return x / y; } };
// Do arithmetic op represented by this constant
abstract double eval(double x, double y);
}
Java programming language enums are far more powerful than their counterparts in other languages, which are little more than glorified integers. The new enum declaration defines a full-fledged class (dubbed an enum type). In addition to solving all the problems(Not typesafe, No namespace, Brittleness and Printed values are uninformative) that exists with following int Enum pattern which was used prior to java 5.0 :
public static final int SEASON_WINTER = 0;
it also allows you to add arbitrary methods and fields to an enum type, to implement arbitrary interfaces, and more. Enum types provide high-quality implementations of all the Object methods. They are Comparable and Serializable, and the serial form is designed to withstand arbitrary changes in the enum type.
Read the full article Java Enums for more details.
Related
I have two classes Float2 && Double2
public final class Float2 {
public float width;
public float height;
public Float2 multiplyBy(float number) {
return new Float2(this.width * number, this.height * number);
}
}
public class Double2 {
public double width;
public double height;
}
I want to cast the result of multiplyBy method to a Double2 so that in the end I do not have Float2 newRectangleSize = rectangleSize.multiplyBy(3.2f); but Double2 newRectangleSize as the result of multiplication. Of course I can cast width and height values separately but I was wondering if there was a more ellegant solution in java?
If Double2 and Float2 would be related types then casting could be possible.
As long as they aren't, you cannot cast them regardless the names of parameters are same including their types. However, you can use this advantage for a framework based on reflection that makes mapping between types easy, such as MapStruct:
#Mapper
public interface Double2Mapper {
Double2Mapper INSTANCE = Mappers.getMapper(Double2Mapper.class);
#Mapping
Double2 floatToDouble(Float2 float2);
}
Double2 double2 = Double2Mapper.INSTANCE.floatToDouble(rectangleSize.multiplyBy(3.2f));
If you are not keen to use a framework (in case of only few specific and simple cases), I offer you two basic ways based on the pure OOP:
A constructor of Double2 using Float2 (assuming the fields remain public):
public Double2(Float2 float2) {
this.width = float2.width;
this.height = float2.height;
}
A method returning such type in the class Float2:
public Double2 asDouble2() {
return new Double2(this.width, this.height);
}
So clearly trying to cast in this case will result in a ClassCastException. One option would be to support an interface that is implemented by both classes that allows width() and height() to be defined as Number objects or even a type that extends Number. Then you could handle conversion on a implementation by implementation basis to handle precision loss in cases like int or short.
interface Size<T extends Number> {
T width();
T height();
}
Another option might be to provide static factory methods to these classes to allow for the conversion of Double2 to Float2 and vice versa. It might look like this;
public class Double2 {
private final double width;
private final double height;
public Double2(double width, double height) {
this.width = width;
this.height = height;
}
public static Double2 valueOf(Float2 float) {
return new Double2((double) float.width, (double) float.height);
}
}
Float2 float2 = new Float2(2f, 2f).multiplyBy(2f);
Double2 double2 = Double2.valueOf(float2);
So I have a field called optionType and I want it to be able to take on 4 different integer values corresponding to certain options. For example optionType = 0 means the user wants to handle something a certain way, optionType = 1 means another way, etc.
But numbers by themselves are meaningless so I wanted to define constants instead in the class.
public class MyClass {
public static final int OPTION_TYPE_DO_THIS = 0;
public static final int OPTION_TYPE_DO_THAT = 1;
public static final int OPTION_TYPE_DO_SOMETHING_ELSE = 2;
public static final int OPTION_TYPE_DO_COOL_THING = 3;
private int optionType;
....
Is it considered normal to define all the constants out like that or is it better to use an enum like
public enum OPTION_TYPE {DO_THIS, DO_THAT, DO_SOMETHING_ELSE, DO_COOL_THING};
Or am I supposed to be using Enum instead somehow?
The key point is more on "how will that information be used at runtime". You see, if you starting thinking about writing code such as
switch(someEnum) {
case DO_THIS: ...
case DO_THAT:
... then you are already going into the wrong direction!
The point is: very often think that enums (or their even-more-low-level numeric constant cousins) are a good way to express such designs.
But that actually leads to quite some problems. Very often, the better, "more OO" way of thing is to use some abstract base class with specific subclasses; in other words: polymorphism!
Edit: just to make that more clear ... a "single" switch over an enum isn't really a problem. But far too often, people end up with many many places in code where they switch over their enums. And all of those places might need updates when you create additional enum constants. A coworker of mine calls that the "enum trap".
Take a look at this question and answer,
Even though it is written in the C# context, the conclusion states that:
Enums are great for lightweight state information.
Static class members would be able to support this multiple state without any extra functionality.
In java enums are more than just "enumerated names" as they are in other language (e.g. in C/C++).
My preferred use is to provide stateless behavior:
class Calculator {
enum Operation {
ADD{
double calculate(double a, double b){ return a + b;}
}
SUB{
double calculate(double a, double b){ return a - b;}
}
MUL{
double calculate(double a, double b){ return a * b;}
}
DIV{
double calculate(double a, double b){ return a / b;}
}
abstract double calculate(double a, double b);
}
Map<String,Operation> operations = new HashMap<>();
Calculator(){
operations.put("+",ADD);
operations.put("-",SUB);
operations.put("*",MUL);
operations.put("/",DIV);
}
public double calculate(double a, String operation, double b){
return operations.get(operation).calculate(a,b);
}
}
I am not primarily a Java programmer... I would like to find a corresponding Java syntax for class storing a function pointer (templatized) as a variable. The function pointer points to a function "outside" the class. The original code is in C++11:
#include <memory>
template <typename T>
using p_function = T(*)(T, T, T);
template <typename T>
class A
{
private:
int k;
p_function<T> pf;
public:
A() { pf = NULL; k = 0; }
A(p_function<T> pf_, int k_) { pf = pf_; k = k_; }
T getF(const T a1, const T a2, const T a3) const { return pf(a1, a2, a3); }
};
template <typename T>
T f1(T x, T y, T z) { return x + y + z; }
template <typename T>
T f2(T x, T y, T z) { return x - y - z; }
int main()
{
A<double> aa (f1<double>, 1.0);
double val= aa.getF(1.0, 2.0, 3.0);
}
Thinking about the problem, is it reasonable to use the interface?
public interface Function <T> {
T pf(T x, T y, T z);
}
or, is there any better way? Java is relatively rapidly develops, there might be "straighter" constructions than few years ago. There are several requirements which I am not able to join together. Could I ask for a short code sample in Java? Thank you very much for your help.
Use java 8. That uses "functional" interfaces (indeed) where an interface defines just one single function.
To not overuse the existing Function class, introduce your own name.
#FunctionalInterface
public interface TriFunction<T> {
T apply(T x, T y, T z);
}
Marking it with the FunctionalInterface annotation is a practice that prevents adding a second function and such.
class Foo {
public static Bar hop(Bar x, Bar y, Bar z) { ... }
}
TriFunction<Bar> pf = Foo::hop;
TriFunction<Integer> pg = (x, y, z) -> x + y + z;
Bar bara = pf.apply(a, b, c);
For primitive types better define own interfaces without generic parameter types. Above pg needs 3 times to unbox the wrapper objects, and one time to box it again to an object.
The package java.util.function contains many functional interfaces, like BinaryOperator and IntBinaryOperator.
In Java 8, you can use method references. More information here: https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
Basically, Java 8 gives interfaces with only one method the special property that they can be used (sort of) like function pointers. You can assign a lambda or a method reference to an object of such a type.
For example, somewhat related to your question:
public class HelloWorld {
public interface Function <T> {
T op(T x, T y);
}
public static class Functions {
static int add(int x, int y) { return x + y; }
static int sub(int x, int y) { return x - y; }
}
static Function<Integer> f1, f2; // <-- "function pointer"
public static void main(String []args) {
f1 = Functions::add; // <-- static method reference
f2 = Functions::sub; // <-- static method reference
System.out.println("Test: " + f1.op(1,2) + ", " + f2.op(1,2));
}
}
This code prints, as you'd expect:
Test: 3, -1
So that part of your question should work. However, the part where you define a generic addition is more problematic, because Java doesn't allow you to overload the operator '+'. So the following will not compile in Java:
T add(T x, T y) {
return x + y; // compile error -> no '+' defined for T
}
If you need T to be base types, you'll need to define your f1 and f2 for each base type you want to use. See also this question: Can I do arithmetic operations on the Number baseclass?
I am not sure if I get your question correctly, but have a look at this stackoverflow post.
There are several answers on how to implement function pointer in java.
EDIT
I am not experienced enough in C++ to provide a code sample.
EDIT 2
According to the post I mentioned above, you could try something like this:
public class WithFunction {
//Empty constructor, can be left out
public WithFunction () {...}
//The function you want to reference
public int myReferencedFunction () {...}
}
Then
public class MethodCaller {
public static Object call (Object theObject, String methodName) {
return theObject.getClass().getMethod(methodName).invoke(theObject);
//catch Exceptions
}
}
Then you can have it like
public static void main (String [] args) {
WithFunction obj1 = new WithFunction();
Object result = MethodCaller.call (obj1, "toString");
int result = (int) MethodCaller.call (obj1, "myReferencedFunction");
}
Notice:
You need to catch a lot of exceptions. Strong error handling needed..
If you use an interface, you can also implement it multiple times and should have the freedom you need
I have an Operator interface for handling math operator that has two method like so:
public interface Operator
{
double calculate(double firstNumber,double secondNumber);
char getSign();
}
for each operator I have a class that implement Operator interface like so:
public class Plus implements Operator
{
public double calculate(double firstNumber,double secondNumber)
{
return firstNumber + secondNumber;
}
public char getSign()
{
return '+';
}
}
And so on...
In this code I use Reflections :
Reflections reflections = new Reflections("mypackage");
Set<Class<? extends Operator>> classes = reflections.getSubTypesOf(Operator.class);
Reflections is not the part of java Reflection API.I should just use java Reflection capability.
Can anyone help me to change this code that only use java Reflection API?
Instead of using the Reflections API, you can
search your class path for directories and JARs
for the directories look for each class file
for the JAR scan through the files for each class file
read the byte code of the class file with a library like ASM.
if the class implement your interface add it
otherwise check all the super classes and interfaces of the class to see if they implement the interface.
The reason you have to read the byte code is you want to avoid loading all the classes just to see the inheritance hierarchy, esp as some of the classes might not load or could take a long time.
Needless to say, using a library which does this for you is easier. If youw ant to write this yourself I suggest you read the source of the Reflections API to see how it does it.
A simpler solution is to use an enum
enum Operators implement Operator {
PLUS {
public double calculate(double x, double y) {
return x + y;
}
public char getSign() {
return '+';
}
},
MINUS {
public double calculate(double x, double y) {
return x - y;
}
public char getSign() {
return '-';
}
},
TIMES {
public double calculate(double x, double y) {
return x * y;
}
public char getSign() {
return '*';
}
},
DIVIDE {
public double calculate(double x, double y) {
return x / y;
}
public char getSign() {
return '/';
}
}
}
To get all the operators you can use
Operator[] operators = Operators.values();
You cannot scan the class path for the sub types. If you can correlate, even for JPA you would have to specify the entity names as part of configuration. Use a similar approach to specify the list of classes you like to scan through and check if the instanceof. Reflections API only can help with you in that case if not.
If I have an enum object, is it considered a primitive or a reference?
It's a reference type. Java primitives are boolean byte short char int long float double.
You can get the enumeration constant's value by calling ordinal(), which is used by EnumSet and EnumMap iterator and "traverses the elements in their natural order (the order in which the enum constants are declared)"
You can even add your own members to the enum class, like this:
public enum Operation {
PLUS { double eval(double x, double y) { return x + y; } },
MINUS { double eval(double x, double y) { return x - y; } },
TIMES { double eval(double x, double y) { return x * y; } },
DIVIDE { double eval(double x, double y) { return x / y; } };
// Do arithmetic op represented by this constant
abstract double eval(double x, double y);
}
//Elsewhere:
Operation op = Operation.PLUS;
double two = op.eval(1, 1);
The way enums work is actually not too different from how they were used before their introduction with Java 5:
public final class Suit {
public static final Suit CLUBS = new Suit();
public static final Suit DIAMONDS = new Suit();
public static final Suit HEARTS = new Suit();
public static final Suit SPADES = new Suit();
/**
* Prevent external instantiation.
*/
private Suit() {
// No implementation
}}
By instantiating the different suits on class loading it is ensured that these will be mutually exclusive and the private constructor ensures that no further instances will be created.
These would be comparable either through == or equals.
The Java 5 enum works pretty much the same way, but with some necessary features to support serialization etc.
I hope this background sheds some further light.
This article essentially shows you how enums are implemented, and as SLaks says, they are references.
Enums are reference types, in that they can have methods and can be executed from command line as well , if they have main method.
See following "Planet" example from Sun/Oracle
http://download.oracle.com/javase/tutorial/java/javaOO/enum.html