I would like to know what is the difference of Enum between C and Java. And is there a way to "translate" a C enum into a Java enum ?
That's because I have an enum written in C on a robot containing types messages and I need to have the same in Java so that it could read data i send from an app.
In C, an enumeration is just a set of named, integral constants. In Java, an enumeration is more like a named instance of a class. You have the ability to customize the members available on the enumeration.
Also, C will implicitly convert enum values to their integral equivalent, whereas the conversion must be explicit in Java.
For More Information Visit:
Enum In C & Enum In Java
Java Enum is different from C Enum, because in Java Enum is a kind of class, when C\C++ enums is constant, that can be used in indexed expressions and as operands. Also, C\C++ enumerations provide an alternative to the #define preprocessor directive.
P.S.: To get more information, read Effective Java (http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683) 6th chapter (item 30-37) about it, the usage and the differences with C\C++ enums.
Opposed to C, which uses enum as a set of named constants, Java implements it as a class. And if you are concerned about performance do not use it in Android (The Price of enums).
Related
We can create a generic class in Java like this
public class MyClass<T> {
...
but, now that i'm translating a (very large) C++ code to Java, i need a class to be different from other depending on its size, like in this c++ code:
template<size_t size> class MyClass {
...
so every class is a different type, there static members are different, and members like "compare" can only be used with objects with the same size.
Is possible to do this in Java? if not, how would you handle this?
Sure, but it sucks.
You can model "counting' with a chain of recursive types. Inc<Inc<Inc<Integer>> could represent 3.
It is exceedingly awkward.
Java generics are not C++ templates. Java generics have a common base implementation and auto write some wrapping code to cast parameterized arguments to/from a common base in a thin wrapper.
C++ templates generate distinct types.
The design of C++ templates was to replace code generation and/or hand-rolled C code low level data structures. The goal was a template class could match or even exceed hand-written C versions (exceed because you can invest more engineering effort into the single template, and reuse it in 100s of spots).
Templates like std::function more closely approach Java generics. While the implementation is dissimilar, here it converts a myriad of types to one interface, hiding the casting from the end user. In C++ this technique is called type erasure, where std function "erases" all information about the stored callable except what it exposes. C++ type erasure does not require a common base class; Java does.
But because Java generics only supports one kind of type erssure, and C++ templates support not only more kinds of type erasure but also entitely different metaprogramming techniques that are alien to Java, replacing templates with Java generics is going to consistently run into problems. Only when the C++ use case happens to perfectly line up with the weaker Java generics does it work right.
(Note that, while weaker, Java generics make type erasure far easier, because they write a bunch of the casting code for you, and type check it. Weaker doesn't mean worse; it often means safer. But mechanically replacing a system with a weaker one often is doomed to failure.)
No, you can't use values as parameters instead of a generic type in Java. You should probably just take the size as a parameter in the constructor and implement safety checks taking the size into account.
An enum is a specialized class that holds a set of constants. If we wanted to declare a field (variable) to be a constant in Java, we would use the keyword final. When should we use an enum over a regular constant variable?
Advantage of enum: type-safety
For example, considering the months, if we have constants as int (static final int JANUARY = 1)1 then a variable or method parameter must be declared as int and would accept any integer value , valid or not(e.g. setMonth(123) or setMonth(0)).
If we have an enum, then the variables or method parameters can only accept its values - errors (wrong constants) can be detected at compile time (exception: null which can also be assigned/passed instead of an enum, like any reference type).
1: not the same definition as from Calendar (JANUARY = 0)
Official Oracle tutorial Enum Types:
You should use enum types any time you need to represent a fixed set of constants. That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile timeāfor example, the choices on a menu, command line flags, and so on.
Enums are typically used for groups of constants that are related. For example, shirt_sizes may be an enum of Small, Medium, Large, X-Large and so on. These will always be the same and we know what they are at the time we write the program.
If you want further reading that helps to explain why we use enums, check out this article https://crunchify.com/why-and-for-what-should-i-use-enum-java-enum-examples/
If Enums are an answer for getting rid of compile time constants , why did the language designers provide facility to let arbitrary methods and fields and implement arbitrary interfaces on Enums ? Those methods can never change the state of the Enum instances or can they ? If they are allowed to change the state , then the invariant of an Enum type ie some type that exports a few constants will break IMHO.
Java enums are really just classes with some special treatment by the compiler and runtime. So yes, method calls on an enum instance can certainly change its state. I'm not sure what you mean with "then the invariant of an Enum type ie some type that exports a few constants will break".
Who says enums can only be a bunch of constants? The essence of an enum type is that you have a predefined fixed number of instances which you can refer to by name - and Java enums implement that. But why would a language not be allowed to have enums that are more powerful than that?
If you don't want the extra power, nobody forces you to use it. You can have Java enums without fields or methods, and they'll behave pretty much exactly like C enums.
Enums are compile-time constants, but their members aren't. It's usually not a good idea to change enum members at runtime, but it is possible. For this reason, you can't use an enum's members where compile-time constants are called for (e.g. in annotation parameters).
Hardly anything in Java is really a constant when you go try hard to mess things up. E.g. a String constant contains a char array. Arrays are not immutable. Here's an example of the mess you can make using inlined String constants:
public static void main(final String[] args) throws Exception {
final Field valueField = String.class.getDeclaredField("value");
valueField.setAccessible(true);
System.arraycopy("frog".toCharArray(), 0,
(char[]) valueField.get(Boolean.TRUE.toString()), 0, 4);
System.out.println(Boolean.parseBoolean("frog")); // true
System.out.println(Boolean.parseBoolean("true")); // false
}
So, Java constants in most cases are just constants as long as your application is well-behaved.
why did the language designers provide facility to let arbitrary methods and fields and implement arbitrary interfaces on Enums
Reasons are to allow replacing switch-statements with polymorphism and generally make programs more Object Oriented by allowing to define methods on the data.
Search for "type-safe enum pattern". Java Enums are an implementation of this design pattern on language level.
This question is inspired from Joel's "Making Wrong Code Look Wrong"
http://www.joelonsoftware.com/articles/Wrong.html
Sometimes you can use types to enforce semantics on objects beyond their interfaces. For example, the Java interface Serializable does not actually define methods, but the fact that an object implements Serializable says something about how it should be used.
Can we have UnsafeString and SafeString interfaces/subclasses in, say Java, that are used in much of the same way as Joel's Hungarian notation and Java's Serializable so that it doesn't just look bad--it doesn't compile?
Is this feasible in Java/C/C++ or are the type systems too weak or too dynamic?
Also, beyond input sanitization, what other security functions can be implemented in this manner?
The type system already enforces a huge number of such safety features. That is essentially what it's for.
For a very simple example, it prevents you from treating a float as an int. That's one aspect of safety -- it guarantees that the type you're working on are going to behave as expected. It guarantees that only string methods are called on a string. Assembly doesn't have that safeguard, for example.
It's also the job of the type system to ensure that you don't call private functions on a class. That's another safety feature.
Java's type system is too anemic to enforce a lot of interesting constraints effectively, but in many other languages (including C++), the type system can be used to enforce far more wide-ranging rules.
In C++, template metaprogramming gives you a lot of tools for prohibiting "bad" code. For example:
class myclass : boost::noncopyable {
...
};
enforces at compile-time that the class can not be copied. The following will produce compile errors:
myclass m;
myclass m2(m); // copy construction isn't allowed
myclass m3;
m3 = m; // assignment also not allowed
Likewise, we can ensure at compile-time that a template function only gets called on types which fulfill certain criteria (say, they must be random-access iterators, while bilinear ones aren't allowed, or they must be POD types, or they must not be any kind of integer type (char, short, int, long), but all other types should be legal.
A textbook example of template metaprogramming in C++ implements a library for computing physical units. It allows you to multiply a value of type "meter" with another value of the same type, and automatically determines that the result must be of type "square meter". Or divide a value of type "mile" with a value of type "hour" and get a unit of type "miles per hour".
Again, a safety feature that prevents you from getting your types mixed up and accidentally getting your units mixed up. You'll get a compile error if you compute a value and try to assign it to the wrong type. trying to divide, say, liters by meters^2 and assigning the result to a value of, say, kilograms, will result in a compile error.
Most of this requires some manual work to set up, certainly, but the language gives you the tools you need to basically build the type-checks you want. Some of this could be better supported directly in the language, but the more creative checks would have to be implemented manually in any case.
Yes you can do such thing. I don't know about Java, but in C++ it isn't customary and there is no support for this, so you have to do some manual work. It is customary in some other languages, Ada for example, which have the equivalent of a typedef which introduces a new type which can't be converted implicitly into the orignal one (this new type "inherits" some basic operations from the one it is created, so it stays usefull).
BTW, in general inheritance isn't a good way to introduce the new types, as even if there is no implicit conversion in one way, there is one in the other one.
You can do a certian amount of this out of the box in Ada. For example, you can make integer types that cannot implcitily interoperate with each other, and Ada enumerations are not compatible with any integer type. You can still convert between them, but you have to explicitly do it, which calls attention to what you are doing.
You could do the same with present-day C++, but you'd have to wrap all your integers and enums in classes, which is just way too much work for something that should be simple (or better yet, the default way of doing things).
I understand the next version of C++ is going to fix at least the enumeration issue.
In C++, I suppose you could use typedef to create a synonym for a primitive type. Your synonym could imply something about the content of that variable, replacing the function of the apps hungarian notation.
Intellisense will report the synonym you used during declaration, so if you don't like using actual hungarian, it does save you from scrolling about (or using Go To Definition).
I guess you are thinking of something along the lines of Perl's "tainting" analysis.
In Java, it should be possible to use custom annotations and an annotation processor to implement this. Not necessarily easy though.
You can't have a UnsafeString subclass of String in Java, since java.lang.String is final.
In general, you cannot provide any kind of security on the source level - if you want to protect against evil code, you must do that on the binary level (e.g. Java bytecode). That's why private/protected can't be used as a security mechanism in C++: it is possible to bypass that with pointer manipulations.
What are some advantages of making enum in Java similar to a class, rather than just a collection of constants as in C/C++?
You get free compile time checking of valid values. Using
public static int OPTION_ONE = 0;
public static int OPTION_TWO = 1;
does not ensure
void selectOption(int option) {
...
}
will only accept 0 or 1 as a parameter value. Using an enum, that is guaranteed. Moreover, this leads to more self documenting code, because you can use code completion to see all enum values.
Type safety is one reason.
Another, that I find more important, is that you can attach metadata to enum values in Java. For example, you could use an enum to define the set of legal operations for a webservice, and then attach metadata for the type of request and data class:
AddItem(HttpMethod.POST, ProductEntry.class),
Java 5 enums originated from a typesafe enum pattern from Joshua Bloch's Effective Java (the first edition) to avoid the pitfalls of enums in C/C++/C# (which are simply thinly-veiled int constants) and the use in Java of final static int constants.
Primarily int constants and int enums aren't typesafe. You can pass in any int value. In C/C++ you can do this:
enum A { one, two, three };
enum B { beef, chicken, pork } b = beef;
void func(A a) { ... }
func((A)b);
Unfortunately the typesafe enum pattern from Effective Java had a lot of boilerplate, not all of it obvious. The most notable is you had to override the private method readResolve to stop Java creating new instances on deserialization, which would break simple reference checking (ie using the == operator instead of equals()).
So Java 5 enums offer these advantages over ints:
Type safety;
Java 5 enums can have behaviour and implement interfaces;
Java 5 enums have some extremely lightweight data structures like EnumSet and EnumMap.
Java 5 enums over these advantages over just using classes:
Less error-prone boilerplate (private constructor, readResolve() etc);
Semantic correctness. You see something is an enum and you know it's just representing a value. You see a class and you're not sure. Maybe there's a static factory method somewhere, etc. Java 5 enums much more clearly indicate intent.
Enums are already a class in Java.
If you're asking why this is better, I'd say that better type safety and the ability to add other attributes besides a mere ordinal value would come to mind.
In addition to better type safety, you can also define custom behavior in your enums (refer to Effective Java for some good examples).
You can use enums to effectively implement Singletons ^^:
public enum Elvis {
INSTANCE
}
Making enum a reference type that can contain fixed set of constants has led to efficient Map implementation like EnumMap and Set implementation like EnumSet (JDK classes).
From javadoc of EnumMap :
A specialized Map implementation for use with enum type keys. All of the keys in an enum map must come from a single enum type that is specified, explicitly or implicitly, when the map is created. Enum maps are represented internally as arrays. This representation is extremely compact and efficient.
EnumMap combines richness and type safety of Map with the speed of an array (Effective Java).
Enums are a type in itself - you cannot use an enum that does not exist, or put in some other similar looking constant. and also, you can enumerate them, so that code can be more concise.
using static constants could potentially cause maintenence nightmares - especially if they area spread out.
The only real advantage is that it can be used in a switch statement. All the other stuff an enum is capable of can just be done with plain vanilla class with a private constructor whose instances in turn are declared as public static final fields of the class in question (the typesafe pattern). The other advantage of enum is obviously that it makes the code less verbose than you would do with a plain vanilla class.
But if I'm not mistaken, in C++ (or was it C#?) you can use a String in a switch statement. So that advantage of enums in Java is negligible as opposed to C++. However, same thing was proposed for Java 7, not sure if it will make it.
Benefits of Using Enumerations:
An object can be created to work in the same manner as an enumeration. In fact,
enumerations were not even included in the Java language until version 5.0. However,
enumerations make code more readable and provide less room for programmer error.
OCA Java SE 7 Programmer I Study Guide