672329 members! Sign up to stay informed.

Sponsored Links


Resources

Enterprise Java
Research Library

Get Java white papers, product information, case studies and webcasts

News News News Messages: 20 Messages: 20 Messages: 20 Printer friendly Printer friendly Printer friendly Post reply Post reply Post reply XML XML XML

Creating Java Enum Objects at Runtime

Posted by: Thomas Mueller on July 30, 2008 DIGG
A Java enum type represents a fixed set of constants. Example:
enum Day { SUN, MON, TUES, WED, THUR, FRI, SAT }
What if you want to add one more day? Usually, you can't, and you may say: "why would I want to do that?". Well, let's say we just want to. If you are interested about my use case, see at the end.

So let's try. First try, extend the enum:
public enum DayPlus extends Day { MYDAY }
This doesn't work, Javac doesn't like 'extends' here. The same if you try 'implements'. What about using reflection?
Day.class.newInstance();
This compiles - but doesn't work as either. After some more tries, I found the solution:
Constructor con = Day.class.getDeclaredConstructors()[0];
Method[] methods = con.getClass().getDeclaredMethods();
for (Method m : methods) {
if (m.getName().equals("acquireConstructorAccessor")) {
m.setAccessible(true);
m.invoke(con, new Object[0]);
}
}
Field[] fields = con.getClass().getDeclaredFields();
Object ca = null;
for (Field f : fields) {
if (f.getName().equals("constructorAccessor")) {
f.setAccessible(true);
ca = f.get(con);
}
}
Method m = ca.getClass().getMethod(
"newInstance", new Class[] { Object[].class });
m.setAccessible(true);
Day v = (Day) m.invoke(ca, new Object[] {
new Object[] { "VACATION", Integer.MAX_VALUE } });
System.out.println(v.getClass() + ":" + v.name() + ":" + v.ordinal());
I know it's a hack. The code does something the Java platform was supposed to disallow. But it works (at least with a Sun JDK).

An now about the use case: I am implementing 'JaQu', which stands for Java Query and is something like LINQ for Java. If you don't know LINQ, it is a Microsoft invention and allows to write 'almost SQL' statements in C# applications, for example:
var sundayWork =
from t in timesheet where t.WeekDay == Day.SUN select t;
This is C# code and may be translated to SQL:
SELECT * FROM TIMESHEET T WHERE T.WEEKDAY='SUN'
Now I like to do that in Java. The best I came up with is:
Timesheet t = new Timesheet();
List<Timesheet> sundayWork =
db.from(t).where(t.weekDay).is(Day.SUN).select();
For that to work I need a unique object in t.weekDay.

If you want to know more about JaQu: it is part of the H2 Database Engine.

You may also be interested in some example JaQu code.

Threaded replies

·  Creating Java Enum Objects at Runtime by Thomas Mueller on Wed Jul 30 21:24:34 EDT 2008
  ·  Seems Class knowlege need updated by Qinxian Xiang on Fri Aug 01 10:02:57 EDT 2008
    ·  Groovy to the rescue by Guillaume Laforge on Fri Aug 01 11:19:06 EDT 2008
    ·  Security flaw? by Brian O'Neill on Fri Aug 01 12:33:43 EDT 2008
      ·  Re: Security flaw? by Jim O'Donnell on Fri Aug 01 13:29:23 EDT 2008
      ·  Re: Security flaw? by Thomas Mueller on Fri Aug 01 14:36:45 EDT 2008
        ·  Re: Security flaw? by Slava Imeshev on Mon Aug 04 12:23:41 EDT 2008
          ·  Re: Security flaw? by Thomas Mueller on Mon Aug 04 20:36:32 EDT 2008
            ·  Re: Security flaw? by Slava Imeshev on Tue Aug 05 00:14:23 EDT 2008
    ·  Re: Seems Class knowlege need updated by Qinxian Xiang on Sun Apr 12 10:29:37 EDT 2009
  ·  Re: Creating Java Enum Objects at Runtime by Alok Singh on Fri Aug 01 23:10:54 EDT 2008
    ·  Re: Creating Java Enum Objects at Runtime by Thomas Mueller on Sat Aug 02 13:19:36 EDT 2008
  ·  Why inheriting from an enum does not make sense by Gaetan Pitteloud on Wed Aug 06 03:27:11 EDT 2008
    ·  Re: Why inheriting from an enum does not make sense by Thomas Mueller on Wed Aug 06 09:31:46 EDT 2008
  ·  Re: Creating Java Enum Objects at Runtime by craig bordelon on Wed Aug 06 17:20:25 EDT 2008
    ·  Re: Creating Java Enum Objects at Runtime by Thomas Mueller on Fri Aug 08 01:57:28 EDT 2008
  ·  Pointless and unnecessary by Inf ernoz on Wed Aug 20 04:17:39 EDT 2008
    ·  Re: Pointless and unnecessary by Thomas Mueller on Thu Aug 21 10:07:26 EDT 2008
  ·  But how does this get added to the original enum? by Matthew Fellows on Wed Aug 27 10:43:39 EDT 2008
    ·  Re: But how does this get added to the original enum? by Thomas Mueller on Thu Aug 28 11:40:47 EDT 2008
  ·  Example of use case by azer azerazer on Sat May 23 00:40:49 EDT 2009
  Message #265198 Post reply Post reply Post reply Go to top Go to top Go to top

Seems Class knowlege need updated

Posted by: Qinxian Xiang on August 01, 2008 in response to Message #265114
java Class updated from enum out.
there are some methods used for handle enum class type.
So enum reflection is not so painfull.
Of couse, Class just an object, not a class hier. It's java's question.

  Message #265202 Post reply Post reply Post reply Go to top Go to top Go to top

Groovy to the rescue

Posted by: Guillaume Laforge on August 01, 2008 in response to Message #265198
You could also use the Groovy shell to evaluate new enums at runtime with something like new GroovyShell().evaluate("my enum code here"). I love one-liners like this :-)

  Message #265205 Post reply Post reply Post reply Go to top Go to top Go to top

Security flaw?

Posted by: Brian O'Neill on August 01, 2008 in response to Message #265198
I'd say what you've done shows a security flaw in the JVM. Enums are supposed to be better than the old technique of passing special int values because you need not check for legal values. By extending the enum, you've shown it is possible to pass values into a method that it almost certainly cannot cope with.

  Message #265209 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Security flaw?

Posted by: Jim O'Donnell on August 01, 2008 in response to Message #265205
I don't think that's going to work if you run with a security manager. setAccessible() requires the ReflectPermission("suppressAccessChecks") permission.

If your security manager is null, then you can go hog wild, however.

  Message #265219 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Security flaw?

Posted by: Thomas Mueller on August 01, 2008 in response to Message #265205
I don't think it's a security flaw: it's easy to protect using a SecurityManager. Almost anything is possible when there is no SecurityManager.

The designers of enum feature decided there is no use case to create new enum objects at runtime. They took great care to not allow it. Unfortunately I need this feature.

It's an unexpected use case, and so the workaround is complicated. I hope in the future there will be an official way to create new enum objects (and a SecurityManager setting for it).

  Message #265242 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Creating Java Enum Objects at Runtime

Posted by: Alok Singh on August 01, 2008 in response to Message #265114
You could try doing something like this:


public static enum WeekDay implements Day {
SUN,
MON,
Tues,
WED,
THUR,
FRI,
SAT;

public int dayOfWeek() {
return ordinal();
}
}

public static enum MyFavoriteDay implements Day {
GoofingOff, WorkFromHome, Vacation;

public int dayOfWeek() {
return ordinal();
}
}



  Message #265253 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Creating Java Enum Objects at Runtime

Posted by: Thomas Mueller on August 02, 2008 in response to Message #265242
You could try doing something like this:
public static enum WeekDay implements Day {
...

Unfortunately you couldn't use switch/case any more. The following doesn't compile:
Day d = WeekDay.SUN;
switch(d) {
case SUN:
...
}


  Message #265425 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Security flaw?

Posted by: Slava Imeshev on August 04, 2008 in response to Message #265219
Unfortunately I need this feature.

It's an unexpected use case


I'm dying to hear what that use case is about.

Regards,

Slava Imeshev
Cacheonix: Distributed Java Cache

  Message #265451 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Security flaw?

Posted by: Thomas Mueller on August 04, 2008 in response to Message #265425
I'm dying to hear what that use case is about.
That is actually in the article. It is needed for JaQu, which is LINQ for Java.

  Message #265457 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Security flaw?

Posted by: Slava Imeshev on August 05, 2008 in response to Message #265451
The article starts with a simple statement that you want to add to enum just because.

Slava

  Message #265549 Post reply Post reply Post reply Go to top Go to top Go to top

Why inheriting from an enum does not make sense

Posted by: Gaetan Pitteloud on August 06, 2008 in response to Message #265114
There is a reason behind the fact that Java does not allow to extend an enum :

Declaring an enum means : "Here is a new class, and the complete list of possible instances of this class are declared in the class". Using "complete", I mean there are no more, no less objects of this type.

When inheriting from a class, you actually restrict the set of possible instances: as an example, think about Integer extends Number extends Object (in opposition, when inheriting from an interface, you actually extend the set of possible instances); XSD describes it better when defining a type based on an existing one: you can choose between <xsd:restriction> and <xsd:extension> elements, where restriction can be seen as concrete (class) inheritance, and extension can be seen as interface inheritance.

Now back to enum. Suppose we have the following enums:
enum Day { SUN, MON, TUE, WED, THU, FRI, SAT }
enum WorkingDay { MON, TUE, WED, THU, FRI }

Now, what extends what ?
1. Day extends WorkingDay (add new constants (SAT, SUN) to WorkingDay): This means Day IS A WorkingDay, which is wrong, the following must raise a compile-time error:
WorkingDay d = Day.SUN;

2. WorkingDay extends Day (remove constants (SAT, SUN) from Day): this might be acceptable regarding OO principles, but useless in common situation. Starting from an enum, the only way is to restrict the possible values. Adding new values to an existing enum means changing its parent hierarchy, which is usually not possible. Further, what would be the top-most enum class, containing all possible declared enum values ?

3. Day extends non-enum concrete class: the goal of an enum is to define a fixed set of immutable objects (instance fields should be declared final). This is not the case for the non-enum parent class: it can define its own instance variables + modifier methods.

4. non-enum class extends Day: the Day enum defines the complete set of instances. The goal of creating a plain class that extends an enum is to create instances of this class, which violates the enum principle.

  Message #265568 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Why inheriting from an enum does not make sense

Posted by: Thomas Mueller on August 06, 2008 in response to Message #265549
When inheriting from a class, you actually restrict the set of possible instances

This sounds wrong to me. In most cases, when a class extends another, you add new fields, which extends the set of possible distinct instances.

  Message #265598 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Creating Java Enum Objects at Runtime

Posted by: craig bordelon on August 06, 2008 in response to Message #265114
Why are you still using Java?
Try Scala and your life will be simpler:

abstract class Day extends Enumeration(0) {
val SUN, MON, TUE, WED, THU, FRI, SAT = Value
}

object Day extends Day

object DayPlus extends Day {
val MYDAY = Value
}

  Message #265675 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Creating Java Enum Objects at Runtime

Posted by: Thomas Mueller on August 08, 2008 in response to Message #265598
Why are you still using Java?
Because most people use Java. From Ohloh.org: Java 3,718 projects, C# 868, Scale 10. Java 1,910,517 commits, Scala 6,167.

Most people use Java in their application. Mixing Java and another language (for example Scala or Groovy) in the same application is complicated. It would be required to split the code to access the database and the application code.

  Message #266439 Post reply Post reply Post reply Go to top Go to top Go to top

Pointless and unnecessary

Posted by: Inf ernoz on August 20, 2008 in response to Message #265114
What you should do is use a common interface for both the Day enum and the WeekDay enum and provide your own integer property. I have done this and it works brilliantly.

e.g.
interface Day {
int value();
}

public enum WeekDay implements IDay {
SUN,MON,TUE,WED,THU,FRI,SAT;
private Day() {}
public int value() {
return ordinal();
}

// int to WeekDay helper.
private final static WeekDay [] array = {SUN,MON,TUE,WED,THU,FRI,SAT};
public final static WeekDay get(int i) {
return array[i];
}
// IDay to WeekDay helper
public final static WeekDay get(IDay day) {
return WeekDay[day.value()];
}
}
public enum WorkingDay implements IDay {
MON(1),TUE(2),WED(3),THU(4),FRI(5);
private final int value;
private WeekDay(int value) {
this.value = value;
}
public int value() {
return value;
}
}

Look how damned easy that was!

  Message #266608 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Pointless and unnecessary

Posted by: Thomas Mueller on August 21, 2008 in response to Message #266439
In the use case I have (JaQu), the enum is defined by the user. That means the following code is fixed and can't be changed:
enum Day { SUN, MON, TUES, WED, THUR, FRI, SAT }
You have added an interface to this class. But it is not possible to add an interface to a class at runtime (after the class is loaded). So your solution can't be used for my tool.

  Message #267445 Post reply Post reply Post reply Go to top Go to top Go to top

But how does this get added to the original enum?

Posted by: Matthew Fellows on August 27, 2008 in response to Message #265114
This is very good for creating the instance of an enum object but isn't this useless unless it gets added to the enum. If you were to call Day.values() and list all the Days you'd not see VACATION in the list. At least when I tried implementing this I didn't...

  Message #267564 Post reply Post reply Post reply Go to top Go to top Go to top

Re: But how does this get added to the original enum?

Posted by: Thomas Mueller on August 28, 2008 in response to Message #267445
For my use case this is not necessary. Is probably possible however using a similar trick. It's probably a bit more complicated because ENUM$VALUES is final.

  Message #307321 Post reply Post reply Post reply Go to top Go to top Go to top

Re: Seems Class knowlege need updated

Posted by: Qinxian Xiang on April 12, 2009 in response to Message #265198
Soooorry, I reviewed, I reply tooooooooooo quick.
So I must admit, "you can be quick, but cannot be too quick":)

  Message #309298 Post reply Post reply Post reply Go to top Go to top Go to top

Example of use case

Posted by: azer azerazer on May 23, 2009 in response to Message #265114
I was trying to do the same thing, but did not find a way. Here's the use case since so many ppl are just saying there is no use case for this. ( :) if there is another way, I'm all hears).

I want to compute matrices together. Those matrices have Sets of data as values. It's huge (billion/trillions or even more) and you have to do lots of comparisons so using an enumSet would be very nice. But then you need an enum Type, and since you don't know all the possible values of the set before you start the program (it comes from an input file), then you cannot use enumSet. The enumType would not be modified in any way, I just want to create it with the right data.

Any ideas are welcome.

Franck

New content on TheServerSide.comNew content on TheServerSide.comNew content on TheServerSide.com

Dependency Injection in Java EE 6 - Part 2

Reza Rahman continues to explore the features of the proposed JSR 299, Contexts and Dependency Injection for Java EE (CDI). When approved, it promises to be a key feature of Java EE 6. (January 21, Article)

Ted Neward Q&A: What you must know about JavaScript, Scala and more

Ted Neward is an independent consultant specializing in high-scale enterprise systems, and an authority in Java and .NET technologies. He is the author and co-author of several books, including Effective Enterprise Java. At TheServerSide Java Symposium in March, he will be presenting sessions on pragmatic architecture, ECMAScript and Scala. (January 15, Article)

Developers split on open sourcing Java

Now that Oracle is absorbing Sun Microsystems, there mixed views on what should come of the Java Community Process (JCP). While some say Oracle should become the new steward of Java and keep the JCP much as it was, others argue that it may be time to open-source this widespread language. (November 24, Article)

Dependency Injection in Java EE 6 - Part 1

Reza Rahman explores the features of the proposed JSR 299, Contexts and Dependency Injection for Java EE (CDI). When approved, it promises to be a key feature of Java EE 6. (November 2, Article)

SAML: It's Not just for Web services

SAML is an XML-based standard for exchanging authentication and authorization data between security domains. The single most important problem that SAML was created to solve is the Web browser Single Sign-On problem. Many organizations are debating whether to stay with version 1.1 or move to 2.0. This article makes observations about both options. (September 28, Article)

Programming is Also Teaching Your Team

Joe Ottinger takes a look at how people learn, and applies it to the practice of programming. He notes that understanding how people learn is an essential part of working in a programming team. (September 22, Article)

Can Java EE Deliver The Asynchronous Web?

Stephen Maryka gave us an article about the Asynchronous Web and posed a number of questions that get examined like an approach to delivering Asynchronous Web capabilities through extensions to existing Java EE technologies. (July 14, Article)

JSF Flex

JavaServer Faces Flex goal is to provide users capability in creating standard Flex components, part of flexSDK which is open sourced through MPL license, as normal JSF components. This article by Ji Hoon Kim will provide an overview of creating a simple multilingual JSF page consisting of JSF Flex tags. (June 29, Article)

The Rules of SOA - A Road to a Successful SOA Implementation

In this session Jeff explores the key characteristics of successful SOA projects. He covers some of the patterns, and anti-patterns, tool sets, and strategies that he himself learned the hard way. Last, he provides a strategy and blueprint for achieving a high likelihood of success in your SOA project. (June 23, Tech Talk)

Ari Zilka Talks About Terracotta 3.1

Ari Zilka, CTO of Terracotta, Inc., talks about the new features in Terracotta 3.1, announced during JavaOne and available now. (June 15, Tech Talk)

Enterprise Application Integration, and Spring

In this Tech Talk, Josh Long explores an integration challenge using Spring Integration and walks through the implementation, employing and expanding on the basic patterns of Enterprise Application Integration to tie together components into a function integration solution, and then demonstrates how Spring Integration helps address the integration requirements. (June 15, Tech Talk)

Google Web Toolkit: An Introduction

In this Tech Talk, David Geary teaches you: The basics of Google Web Toolkit; How to implement Ajax-enabled applications in Java; Internationalization; Hooking into the browser history mechanism; Remote procedure calls. (June 4, Tech Talk)

Just Enough Early Architecture to Guide Development

Jon Kern discusses the best architecture/technical solutions and ensure that they are repeated by all developers. By tackling the architecture up-front in a serial manner, subsequent parallel development will be much more manageable and predictable. (May 28, Tech Talk)

Productive Programmer: On the Lam from the Furniture Police

This keynote describes the frustrations of modern knowledge workers in their quest to actually get some work done, and solutions for how to guard yourself against all those distractions. Neal Ford talks about environments, coding, acceleration, automation, and avoiding repetition as ways to defeat the misguided attempts to sap your ability to produce good work. (May 26, Tech Talk)

Auto-Scaling Your Existing Web Application

Gil demonstrates how new, aggressive uses of already abundant compute capacity by common applications offer competitive value for application designers. (May 21, Tech Talk)

Automating Hibernate Mapping and Queries For Java Web Development

Chris Keene introduces WaveMaker as a new way to automate the ability to generate Hibernate classes in order to more quickly bring OR mapping into an application. (May 19, Article)

Free Book PDF Download: Mastering EJB Third Edition

Mastering EJB was one of the original and most influential EJB books in the industry. Mastering EJB III now returns with two new expert co-authors, updated for EJB 2.1 and 30% new chapters including security, integration, best practices, open source, and more.
(Book PDF Download)

Application Server Matrix

The Application Server Matrix is a detailed listing of J2EE vendors and their application server products, with information on latest version numbers, J2EE spec support and licensing, pricing, platform support, and links to product downloads and reviews.
(Application Server Comparison Matrix)

News | Blogs | Discussions | Tech talks | Patterns | Reviews | White Papers | Downloads | Articles | Media kit | About
Java Solutions
All Content Copyright ©2007 TheServerSide Privacy Policy
Site Map