No enum constant ошибка

Использую JDBC для чтения и записи объектов в DB.

В одном из объектов (Coupon) есть поле типа CouponType (что является enum CouponType).

enum CouponType:

package db_package;

public enum CouponType {
    RESTURANS("RESTURANS"), 
    ELECTRICITY("ELECTRICITY"), 
    FOOD("FOOD"),
    HEALTH("HEALTH"),
    SPORTS("SPORTS"),
    CAMPING("CAMPING"),
    TREVELLING("TREVELLING");


    private String type;

    CouponType(String type) {
        this.type = type;
    }

    public String type() {
        return type;
    }
}

Когда я выполняю метод getCoupon я создаю новый купон заполняю его поля данными из DB, и возвращаю.

class CouponDBDAO() — getCoupon, creatCoupon methods:

public void createCoupon(Coupon coup) {
        Statement st;
        try {
            st = getStatment();
            if(st != null){
            st.execute(SQLConstantsQuery.INSERT_INTO_COUPON_VALUES
                    + "(" + coup.getId() + ",'" + coup.getTitle()
                    + "','" + coup.getStartDate() + "','" + coup.getEndDate() + "'," 
                    + coup.getAmount() + ",'" + coup.getType() + "','" + coup.getMessage()
                    + "'," + coup.getPrice() + ",'" + coup.getImage() + "');");
            System.out.println("Coupon " + coup.getTitle() + " added to DB");
            }else{
                throw new UpdateException("The Statement is null...");
            }
        } catch (SQLException | UpdateException e) {
            e.printStackTrace();
        }
    }


public Coupon getCoupon(long id) {
        //Создание нового объекта Coupon для возврата
        Coupon coupon = new Coupon();
        ResultSet rs;
        String typeFromDB;
        try {
            //Метод getStatment() возвращает Statment далее выполняем SQL запрос и получаем объект Coupon.
            rs = getStatment().executeQuery(SQLConstantsQuery.SELECT_COUPON_BY_ID + id );
            while(rs.next()){
                coupon.setId(rs.getLong(SQLConstantsQuery.COUPON_ID));
                coupon.setTitle(rs.getString(SQLConstantsQuery.COUPON_TITLE));
                coupon.setStartDate(rs.getDate(SQLConstantsQuery.COUPON_START_DATE));
                coupon.setEndDate(rs.getDate(SQLConstantsQuery.COUPON_END_DATE));
                coupon.setAmount(rs.getInt(SQLConstantsQuery.COUPON_AMOUNT));
                typeFromDB = rs.getString(SQLConstantsQuery.COUPON_TYPE);
                CouponType ct = CouponType.valueOf(typeFromDB.toUpperCase(Locale.ENGLISH));
                coupon.setType(ct);
                coupon.setMessage(rs.getString(SQLConstantsQuery.COUPON_MESSAGE));
                coupon.setPrice(rs.getDouble(SQLConstantsQuery.COUPON_PRICE));
                coupon.setImage(rs.getString(SQLConstantsQuery.COUPON_IMAGE));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return coupon;
    }

Все бы хорошо но когда я делаю setType то метод ждет от меня значение типа CouponType, а у меня String.
Но не беда, я делаю:

 CouponType ct = CouponType.valueOf(typeFromDB.toUpperCase(Locale.ENGLISH));

и передаю ct в метод setType.

Теперь можно запустить Main создав перед этим несколько объектов

Main class:

public class MainTest {

        public static void main(String[] args) {

            CouponDBDAO c = new CouponDBDAO();
            Coupon coupon = new Coupon(6, "title4", "message3", "image3", 5.2, "2015-11-23", "2015-12-23", 773,
                    CouponType.HEALTH);
            System.out.println(c.getCoupon(coupon.getId()));
        }
    }

class Coupon:

public class Coupon {
    private long id;
    private String title, message, image;
    private double price;
    private Date startDate, endDate;
    private int amount;

    private CouponType type;
    protected static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-mm-dd", Locale.US);

    public Coupon(){

    }

    public Coupon(long id, String title, String message, String image, double price, 
            String startDate, String endDate, int amount, CouponType type) throws ParseException {
        super();
        this.id = id;
        this.title = title;
        this.message = message;
        this.image = image;
        this.price = price;
        this.startDate = formatter.parse(startDate);
        this.endDate = formatter.parse(endDate);
        this.amount = amount;
        this.type = type;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getStartDate() {
        return formatter.format(this.startDate);
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public String getEndDate() {
        return formatter.format(this.endDate);
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    public CouponType getType() {
        return type;
    }

    public void setType(CouponType type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "Coupon [id=" + id + ", title=" + title + ", message=" + message + ", image=" + image + ", price="
                + price + ", startDate=" + startDate + ", endDate=" + endDate + ", amount=" + amount + ", type=" + type
                + "]";
    }
}

Ну и теперь самое главное что я хочу спросить, после запуска я получаю ошибку:

Exception in thread "main" java.lang.IllegalArgumentException: No enum constant db_package.CouponType.ELECTRICITY                                       
    at java.lang.Enum.valueOf(Unknown Source)
    at db_package.CouponType.valueOf(CouponType.java:1)
    at db_package.CouponDBDAO.getCoupon(CouponDBDAO.java:108)
    at db_package.MainTest.main(MainTest.java:54)

и немогу понять по чему? Ведь есть такая константа.
Подскажите пожалуйста что не так.

Pre-requisite :  Java : Enumeration Handling

Below is example of enumeration by using all implicit methods of enumeration.
Here used wrong value of enumeration as “Saturday” while using month name here that’s why causing this issue.

package enm;

public class EnumTest {

	enum Month{JANNUARY,FEBRUARY,MARCH,APRIL,MAY,JUNE,JULY,AUGUST,SEPTEMBER,OCTOBER,NOVEMBER,DECEMBER};
	enum MonthDetail{
		JANNUARY("January",1),
		FEBRUARY("February",2),
		MARCH("March",3),
		APRIL("April",4),
		MAY("May",5),
		JUNE("June",6),
		JULY("July",7),
		AUGUST("August",8),
		SEPTEMBER("September",9),
		OCTOBER("October",10),
		NOVEMBER("November",11),
		DECEMBER("December",12);

		public String monthName="";
		public int index;

		//Constructor will always private
		private MonthDetail(String monthName,int index)
		{
			this.monthName=monthName;
			this.index=index;
		}
		//Method
		public void showMonthDetail()
		{
			System.out.println(this.index +" : "+this.monthName);
		}
	};
	public static void main(String[] args) {
		for(Month month:Month.values())
		{
	    //Add one because by default enum indexing start from 0
		System.out.println((month.ordinal()+1) +" : "+month.name());
		}
		//Every enum Class provide values method to get list of enums
		for(MonthDetail monthDetail:MonthDetail.values())
		{
			monthDetail.showMonthDetail();
		}

		try
		{
		MonthDetail mnth=MonthDetail.valueOf("Saturday");
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}

	}

}

Output

1 : JANNUARY
2 : FEBRUARY
3 : MARCH
4 : APRIL
5 : MAY
6 : JUNE
7 : JULY
8 : AUGUST
9 : SEPTEMBER
10 : OCTOBER
11 : NOVEMBER
12 : DECEMBER
1 : January
2 : February
3 : March
4 : April
5 : May
6 : June
7 : July
8 : August
9 : September
10 : October
11 : November
12 : December
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant enm.EnumTest.MonthDetail.Saturday
    at java.lang.Enum.valueOf(Enum.java:238)
    at enm.EnumTest$MonthDetail.valueOf(EnumTest.java:1)
    at enm.EnumTest.main(EnumTest.java:49)

Solutions:
Always use valid constant values to resolve this issue and while trying to call this enum.valueOf() method always handle exception so that any exception happen then your program will not terminate.

try {
 MonthDetail mnth=MonthDetail.valueOf("August");
} catch(Exception ex) {
ex.printStackTrace();
}

To learn more on Enumeration follow below link: Java : Enumeration Handling

“Learn From Others Experience»

MyBatis version

3.5.6

Database vendor and version

PostgreSQL 12.4
PostgreSQL Driver 42.2.19
Java 11.0.8

Test case or example project

public class Mybatis {
    public static class History {

        public enum Operation {
            FOO,
            BAR
        }

        int id;
        int userId;
        Operation operation;

        History(int id, Operation operation) {
            this.id = id;
            this.userId = id; // Just for test
            this.operation = operation;
        }
    }

    public static void main(String[] args) throws IOException {
        InputStream stream = Resources.getResourceAsStream("mybatis.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
        try (SqlSession session = factory.openSession()) {
            HistoryMapper mapper = session.getMapper(HistoryMapper.class);

            mapper.insert(new History(1, History.Operation.FOO));
            mapper.insert(new History(2, History.Operation.BAR));
            session.commit();

            mapper.select();
        }
    }
}

HistoryMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="rockworkx.HistoryMapper">
  <select id="select" resultType="History">
    SELECT history.id, history.user_id, history.operation
    FROM history
  </select>

  <insert id="insert" parameterType="History">
    INSERT
    INTO history(id, user_id, operation)
    VALUES (#{id}, #{userId}, #{operation})
  </insert>
</mapper>

mybatis.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
  <settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
  </settings>
  <typeAliases>
    <typeAlias alias="History" type="rockworkx.Mybatis$History" />
  </typeAliases>
  <environments default="postgres">
    <environment id="postgres">
      <transactionManager type="JDBC" />
      <dataSource type="POOLED">
        <property name="driver" value="org.postgresql.Driver" />
        <property name="url" value="jdbc:postgresql://localhost:5432/postgres" />
        <property name="username" value="postgres" />
        <property name="password" value="postgres" />
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="HistoryMapper.xml" />
  </mappers>
</configuration>

Steps to reproduce

When I use an underscored column user_id together with a java Enum type, Mybatis throws a IllegalArgumentException with message No enum constant.
But if I get rid of the underscored column user_id, everything goes well.
And I also confused with the exception message:

Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'user_id' from result set.  Cause: java.lang.IllegalArgumentException: No enum constant rockworkx.Mybatis.History.Operation.1

Why the user_id column is related to the Enum type Operation ?

I guess that some implementation details dealing with underscored column or Enum type may be wrong.

Expected result

Actual result

Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'user_id' from result set.  Cause: java.lang.IllegalArgumentException: No enum constant rockworkx.Mybatis.History.Operation.1
### The error may exist in HistoryMapper.xml
### The error may involve rockworkx.HistoryMapper.select
### The error occurred while handling results
### SQL: SELECT history.id, history.user_id, history.operation     FROM history
### Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'user_id' from result set.  Cause: java.lang.IllegalArgumentException: No enum constant rockworkx.Mybatis.History.Operation.1
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:149)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
	at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80)
	at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:152)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85)
	at com.sun.proxy.$Proxy4.select(Unknown Source)
	at rockworkx.Mybatis.main(Mybatis.java:40)
Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'user_id' from result set.  Cause: java.lang.IllegalArgumentException: No enum constant rockworkx.Mybatis.History.Operation.1
	at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:87)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createUsingConstructor(DefaultResultSetHandler.java:710)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createByConstructorSignature(DefaultResultSetHandler.java:693)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:657)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:630)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:397)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:354)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:328)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:301)
	at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:194)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
	at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63)
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:89)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
	... 7 more
Caused by: java.lang.IllegalArgumentException: No enum constant rockworkx.Mybatis.History.Operation.1
	at java.base/java.lang.Enum.valueOf(Enum.java:240)
	at org.apache.ibatis.type.EnumTypeHandler.getNullableResult(EnumTypeHandler.java:49)
	at org.apache.ibatis.type.EnumTypeHandler.getNullableResult(EnumTypeHandler.java:26)
	at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:85)
	... 24 more

Расскажите, что это за ошибка и как ее исправить?

Поймал такую вот ошибку «java: No enum constant javax.lang.model.element.Modifier.SEALED «
Не могу понять, что это за ошибка, откуда взялась, что с ней делать? В сети информации мало, решил тут спросить


  • Вопрос задан

  • 176 просмотров

Пригласить эксперта

Похоже, у вас версия java до 17 :

...

    /**
     * The modifier {@code sealed}
     * @since 17
     */
    SEALED,


...

Обнови JDK до 17. Да и скоро выйдет JDK 21 (в сентябре 2023 года).


  • Показать ещё
    Загружается…

21 сент. 2023, в 16:00

100000 руб./за проект

21 сент. 2023, в 15:53

10000 руб./за проект

21 сент. 2023, в 15:48

5000 руб./за проект

Минуточку внимания

Answer by Keanu Haley

java.lang.IllegalArgumentException: No enum constant,A call to the method getByName(«columnHeadings») is throwing java.lang.IllegalArgumentException: No enum const class labware.web.component.limsgrid.PropName.columnHeadings but if I replace this method with the following code it just works .,

Questions

,The enum’s «builtin» (implicitly declared) valueOf(String name) method will look up an enum constant with that exact name. If your input is «columnHeadings», you have (at least) three choices:

1.Create companion object with parsing method.

enum class CarsType {
    @Json(name = "SMALL")
    SMALL,
    @Json(name = "BIG")
    BIG;

    companion object {
        fun nullableValueOf(name: String?) = when (name) {
            null -> null
            else -> valueOf(name)
        }
    }
}

2. In Parcerable read place use it like this

data class CarData(
    val carId: String? = null,
    val carType: CarsType?,
    val data: String?
) : Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readString(),
        CarsType.nullableValueOf(parcel.readString()),
        parcel.readString())

Answer by Capri Huang

The enum’s «builtin» (implicitly declared) valueOf(String name) method will look up an enum constant with that exact name. If your input is «columnHeadings», you have (at least) three choices:,Forget about the naming conventions for a bit and just name your constants as it makes most sense: enum PropName { contents, columnHeadings, …}. This is obviously the most convenient.,Enum.valueOf() only checks the constant name, so you need to pass it «COLUMN_HEADINGS» instead of «columnHeadings». Your name property has nothing to do with Enum internals.,Implement your own lookup method instead of the builtin valueOf to find the corresponding constant for an input. This makes most sense if there are multiple possible mappings for the same set of constants.

Enum.valueOf() only checks the constant name, so you need to pass it "COLUMN_HEADINGS" instead of «columnHeadings». Your name property has nothing to do with Enum internals.

Enum.valueOf()

Enum.valueOf() only checks the constant name, so you need to pass it "COLUMN_HEADINGS" instead of «columnHeadings». Your name property has nothing to do with Enum internals.

"COLUMN_HEADINGS"

Enum.valueOf() only checks the constant name, so you need to pass it "COLUMN_HEADINGS" instead of «columnHeadings». Your name property has nothing to do with Enum internals.

name

Answer by Pablo Randolph

Is there a problem with this formulation?,Any ideas as to what I am doing wrong here ?,To address the questions/concerns in the comments:,The reason is that you always have the possibility to override an in-class initializer list in the constructor. So I guess that in the end, it could be very confusing.

This question is basically an extension of my previous question . I asked the previous question to be sure that the Enum constants are populated when the class loads . Here’s is my class again with the addition of a simple method getByName :

public enum PropName {

  CONTENTS("contents"),
  USE_QUOTES("useQuotes"),
  ONKEYDOWN("onkeydown"),
  BROWSER_ENTIRE_TABLE("browseEntireTable"),
  COLUMN_HEADINGS("columnHeadings"),
  PAGE_SIZE("pageSize"),
  POPUP_TITLE("popupTitle"),
  FILTER_COL("filterCol"),
  SQL_SELECT("sqlSelect"),
  ;

  private String name;

  private PropName(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public static PropName getByName(String name){
    return   PropName.valueOf(name);
  }
}

A call to the method getByName("columnHeadings") is throwing java.lang.IllegalArgumentException: No enum const class labware.web.component.limsgrid.PropName.columnHeadings but if I replace this method with the following code it just works .

 public static PropName getByName(String name){
    for(PropName prop : values()){
      if(prop.getName().equals(name)){
        return prop;
      }
    }

    throw new IllegalArgumentException(name + " is not a valid PropName");
  }

Answer by Deacon Ahmed

What is the reason for java.lang.IllegalArgumentException: No enum const class even though iterating through values() works just fine?, How to cast a variable to certain runtime type got from TypeCast in Scala Scala | 1 week ago , fastd/migration 使用 PHP | 2 months ago , elao/form-bundle Installation PHP | 2 months ago

1.public enum PropName {2.3.  CONTENTS("contents"),4.  USE_QUOTES("useQuotes"),5.  ONKEYDOWN("onkeydown"),6.  BROWSER_ENTIRE_TABLE("browseEntireTable"),7.  COLUMN_HEADINGS("columnHeadings"),8.  PAGE_SIZE("pageSize"),9.  POPUP_TITLE("popupTitle"),10.  FILTER_COL("filterCol"),11.  SQL_SELECT("sqlSelect"),12.  ;13.14.  private String name;15.16.  private PropName(String name) {17.    this.name = name;18.  }19.20.  public String getName() {21.    return name;22.  }23.24.  public static PropName getByName(String name){25.    return   PropName.valueOf(name);26.  }27.}28.

Answer by Gianni O’Neal

There are several ways to solve the same problem. Some are better than others.,Here’s the enum we will be using in our examples. Let’s pick a more complex enum to also showcase looking an enum up by another field.,The following all work by using an index in the form of a Map. There are some minor differences as well as boilerplate concerns.,This exact same approach can be used for additional fields of the enum. It’s not uncommon to want to look up an enum by its display name or some other property.

Here’s the enum we will be using in our examples. Let’s pick a more complex enum to also showcase looking an enum up by another field.

public enum CardColor {
    RED,
    BLACK,
    ;
}

// Jackson annotation to print the enum as an Object instead of the default name.
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum CardSuit {
    // Unicode suits - https://en.wikipedia.org/wiki/Playing_cards_in_Unicode
    SPADE("Spade", String.valueOf((char) 0x2660), CardColor.BLACK),
    HEART("Heart", String.valueOf((char) 0x2665), CardColor.RED),
    DIAMOND("Diamond", String.valueOf((char) 0x2666), CardColor.RED),
    CLUB("Club", String.valueOf((char) 0x2663), CardColor.BLACK),
    ;

    private String displayName;
    private String symbol;
    private CardColor color;
    private CardSuit(String displayName, String symbol, CardColor color) {
        this.displayName = displayName;
        this.symbol =  symbol;
        this.color = color;
    }
    public String getDisplayName() {
        return displayName;
    }
    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }
    public String getSymbol() {
        return symbol;
    }
    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }
    public CardColor getColor() {
        return color;
    }
    public void setColor(CardColor color) {
        this.color = color;
    }

Using Enum.valueOf is great when you know the input is valid. However, if you pass in an invalid name, an exception will be thrown. In some cases, this is fine. Oftentimes. we would prefer to just ignore it and return null.

log.debug("Running valueOf");
for (String name : names) {
    try {
        log.debug("looking up {} found {}", name, Json.serializer().toString(CardSuit.valueOf(name)));
    } catch (Exception ex) {
        log.warn("Exception Thrown", ex);
    }
}
2017-02-22 14:46:38.556 [main] DEBUG c.s.examples.common.EnumLookup - Running valueOf
2017-02-22 14:46:38.804 [main] DEBUG c.s.examples.common.EnumLookup - looking up SPADE found {"displayName":"Spade","symbol":"♠","color":"BLACK"}
2017-02-22 14:46:38.806 [main] DEBUG c.s.examples.common.EnumLookup - looking up HEART found {"displayName":"Heart","symbol":"♥","color":"RED"}
2017-02-22 14:46:38.806 [main] DEBUG c.s.examples.common.EnumLookup - looking up DIAMOND found {"displayName":"Diamond","symbol":"♦","color":"RED"}
2017-02-22 14:46:38.806 [main] DEBUG c.s.examples.common.EnumLookup - looking up CLUB found {"displayName":"Club","symbol":"♣","color":"BLACK"}
2017-02-22 14:46:38.808 [main] WARN  c.s.examples.common.EnumLookup - Exception Thrown
java.lang.IllegalArgumentException: No enum constant com.stubbornjava.examples.common.EnumLookup.CardSuit.Missing
  at java.lang.Enum.valueOf(Enum.java:238)
  at com.stubbornjava.examples.common.EnumLookup$CardSuit.valueOf(EnumLookup.java:1)
  at com.stubbornjava.examples.common.EnumLookup.main(EnumLookup.java:154)

This bad practice is most commonly made by beginners. Exceptions shouldn’t be used for control flow and could have some performance implications. Don’t be lazy. Do it the right way.

/*
 * Please don't do this! Using try / catch for
 * control flow is a bad practice.
 */
public static CardSuit trycatchValueOf(String name) {
    try {
        return CardSuit.valueOf(name);
    } catch (Exception ex) {
        log.warn("Exception Thrown", ex);
        return null;
    }
}
log.debug("Running trycatchValueOf");
for (String name : names) {
    log.debug("looking up {} found {}", name, Json.serializer().toString(CardSuit.trycatchValueOf(name)));
}
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - Running trycatchValueOf
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - looking up SPADE found {"displayName":"Spade","symbol":"♠","color":"BLACK"}
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - looking up HEART found {"displayName":"Heart","symbol":"♥","color":"RED"}
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - looking up DIAMOND found {"displayName":"Diamond","symbol":"♦","color":"RED"}
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - looking up CLUB found {"displayName":"Club","symbol":"♣","color":"BLACK"}
2017-02-22 14:46:38.809 [main] WARN  c.s.examples.common.EnumLookup - Exception Thrown
java.lang.IllegalArgumentException: No enum constant com.stubbornjava.examples.common.EnumLookup.CardSuit.Missing
  at java.lang.Enum.valueOf(Enum.java:238)
  at com.stubbornjava.examples.common.EnumLookup$CardSuit.valueOf(EnumLookup.java:1)
  at com.stubbornjava.examples.common.EnumLookup$CardSuit.trycatchValueOf(EnumLookup.java:89)
  at com.stubbornjava.examples.common.EnumLookup.main(EnumLookup.java:171)
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - looking up Missing found null

This approach is also quite common (see here), but at least the authors know not to try/catch the exceptions. What is wrong with this approach? It’s iterating over all enums until it finds the matching enum or returning null — with a worst case of N, where N is the number of enum values. Some may argue this is being nitpicky and it’s premature optimization. However, data structures and algorithms are CS fundamentals. It’s not that much effort to use a Map instead of iterating a collection. Will it drastically improve performance? No, but it is a good habbit. When interviewing a candidate for a job, would you be happy with a linear complexity search algorithm? You shouldn’t let this code review pass in that case.

/*
 * Please don't do this! It is inefficient and it's
 * not very hard to use Guava or a static Map as an index.
 */
public static CardSuit iterationFindByName(String name) {
    for (CardSuit suit : CardSuit.values()) {
        if (name.equals(suit.name())) {
            return suit;
        }
    }
    return null;
}
log.debug("Running iteration");
for (String name : names) {
    log.debug("looking up {} found {}", name, Json.serializer().toString(CardSuit.iterationFindByName(name)));
}
2017-02-22 14:46:38.808 [main] DEBUG c.s.examples.common.EnumLookup - Running iteration
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - looking up SPADE found {"displayName":"Spade","symbol":"♠","color":"BLACK"}
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - looking up HEART found {"displayName":"Heart","symbol":"♥","color":"RED"}
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - looking up DIAMOND found {"displayName":"Diamond","symbol":"♦","color":"RED"}
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - looking up CLUB found {"displayName":"Club","symbol":"♣","color":"BLACK"}
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - looking up Missing found null

What is the correct data structure to use for quick lookups of fixed size? A HashMap. Now with a little extra boilerplate, we have a much more efficient lookup as long as we have a good hash function. A bit more verbose, and it would be nice if there was a way to reduce the boilerplate.

private static final Map<String, CardSuit> nameIndex =
        Maps.newHashMapWithExpectedSize(CardSuit.values().length);
static {
    for (CardSuit suit : CardSuit.values()) {
        nameIndex.put(suit.name(), suit);
    }
}
public static CardSuit lookupByName(String name) {
    return nameIndex.get(name);
}
log.debug("Running lookupByName");
for (String name : names) {
    log.debug("looking up {} found {}", name, Json.serializer().toString(CardSuit.lookupByName(name)));
}
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - Running lookupByName
2017-02-22 14:46:38.809 [main] DEBUG c.s.examples.common.EnumLookup - looking up SPADE found {"displayName":"Spade","symbol":"♠","color":"BLACK"}
2017-02-22 14:46:38.810 [main] DEBUG c.s.examples.common.EnumLookup - looking up HEART found {"displayName":"Heart","symbol":"♥","color":"RED"}
2017-02-22 14:46:38.810 [main] DEBUG c.s.examples.common.EnumLookup - looking up DIAMOND found {"displayName":"Diamond","symbol":"♦","color":"RED"}
2017-02-22 14:46:38.813 [main] DEBUG c.s.examples.common.EnumLookup - looking up CLUB found {"displayName":"Club","symbol":"♣","color":"BLACK"}
2017-02-22 14:46:38.813 [main] DEBUG c.s.examples.common.EnumLookup - looking up Missing found null

This is such a common use case that our friends over at Google made a very clean and boilerplate-free solution for us. Under the hood, it even uses WeakReferences and WeakHashMaps. Basically, this code will create a global static map keyed on the Enum’s class name and use it for lookups.

public static CardSuit getIfPresent(String name) {
    return Enums.getIfPresent(CardSuit.class, name).orNull();
}
log.debug("Running Guava getIfPresent");
for (String name : names) {
    log.debug("looking up {} found {}", name, Json.serializer().toString(CardSuit.getIfPresent(name)));
}
2017-02-22 14:46:38.813 [main] DEBUG c.s.examples.common.EnumLookup - Running Guava getIfPresent
2017-02-22 14:46:38.814 [main] DEBUG c.s.examples.common.EnumLookup - looking up SPADE found {"displayName":"Spade","symbol":"♠","color":"BLACK"}
2017-02-22 14:46:38.814 [main] DEBUG c.s.examples.common.EnumLookup - looking up HEART found {"displayName":"Heart","symbol":"♥","color":"RED"}
2017-02-22 14:46:38.815 [main] DEBUG c.s.examples.common.EnumLookup - looking up DIAMOND found {"displayName":"Diamond","symbol":"♦","color":"RED"}
2017-02-22 14:46:38.815 [main] DEBUG c.s.examples.common.EnumLookup - looking up CLUB found {"displayName":"Club","symbol":"♣","color":"BLACK"}
2017-02-22 14:46:38.815 [main] DEBUG c.s.examples.common.EnumLookup - looking up Missing found null

Same approach as above, but indexed on the display name instead of the enum name.

private static final Map<String, CardSuit> displayNameIndex =
        Maps.newHashMapWithExpectedSize(CardSuit.values().length);
static {
    for (CardSuit suit : CardSuit.values()) {
        displayNameIndex.put(suit.getDisplayName(), suit);
    }
}
public static CardSuit lookupByDisplayName(String name) {
    return displayNameIndex.get(name);
}
log.debug("Running lookupByDisplayName");
for (String displayName : displayNames) {
    log.debug("looking up {} found {}", displayName, Json.serializer().toString(CardSuit.lookupByDisplayName(displayName)));
}
2017-02-22 14:46:38.815 [main] DEBUG c.s.examples.common.EnumLookup - Running lookupByDisplayName
2017-02-22 14:46:38.815 [main] DEBUG c.s.examples.common.EnumLookup - looking up Spade found {"displayName":"Spade","symbol":"♠","color":"BLACK"}
2017-02-22 14:46:38.815 [main] DEBUG c.s.examples.common.EnumLookup - looking up Heart found {"displayName":"Heart","symbol":"♥","color":"RED"}
2017-02-22 14:46:38.815 [main] DEBUG c.s.examples.common.EnumLookup - looking up Diamond found {"displayName":"Diamond","symbol":"♦","color":"RED"}
2017-02-22 14:46:38.816 [main] DEBUG c.s.examples.common.EnumLookup - looking up Club found {"displayName":"Club","symbol":"♣","color":"BLACK"}
2017-02-22 14:46:38.816 [main] DEBUG c.s.examples.common.EnumLookup - looking up Missing found null

We can’t leverage Guava here, since it would be difficult to create unique global keys for the static index. However, that doesn’t mean we can’t make our own helpers!

public class EnumUtils {

    public static <T, E extends Enum<E>> Function<T, E> lookupMap(Class<E> clazz, Function<E, T> mapper) {
        @SuppressWarnings("unchecked")
        E[] emptyArray = (E[]) Array.newInstance(clazz, 0);
        return lookupMap(EnumSet.allOf(clazz).toArray(emptyArray), mapper);
    }

    public static <T, E extends Enum<E>> Function<T, E> lookupMap(E[] values, Function<E, T> mapper) {
        Map<T, E> index = Maps.newHashMapWithExpectedSize(values.length);
        for (E value : values) {
            index.put(mapper.apply(value), value);
        }
        return (T key) -> index.get(key);
    }
}

Now we have a fairly boilerplate-free generic solution.

private static final Function<String, CardSuit> func =
        EnumUtils.lookupMap(CardSuit.class, e -> e.getDisplayName());
public static CardSuit lookupByDisplayNameUtil(String name) {
    return func.apply(name);
}
log.debug("Running lookupByDisplayNameUtil");
for (String displayName : displayNames) {
    log.debug("looking up {} found {}", displayName, Json.serializer().toString(CardSuit.lookupByDisplayNameUtil(displayName)));
}
2017-02-22 14:46:38.816 [main] DEBUG c.s.examples.common.EnumLookup - Running lookupByDisplayNameUtil
2017-02-22 14:46:38.816 [main] DEBUG c.s.examples.common.EnumLookup - looking up Spade found {"displayName":"Spade","symbol":"♠","color":"BLACK"}
2017-02-22 14:46:38.816 [main] DEBUG c.s.examples.common.EnumLookup - looking up Heart found {"displayName":"Heart","symbol":"♥","color":"RED"}
2017-02-22 14:46:38.816 [main] DEBUG c.s.examples.common.EnumLookup - looking up Diamond found {"displayName":"Diamond","symbol":"♦","color":"RED"}
2017-02-22 14:46:38.816 [main] DEBUG c.s.examples.common.EnumLookup - looking up Club found {"displayName":"Club","symbol":"♣","color":"BLACK"}
2017-02-22 14:46:38.816 [main] DEBUG c.s.examples.common.EnumLookup - looking up Missing found null

Answer by Collins Erickson

Below is example of enumeration by using all implicit methods of enumeration.Here used wrong value of enumeration as “Saturday” while using month name here that’s why causing this issue.,Pre-requisite :  Java : Enumeration Handling,To learn more on Enumeration follow below link: Java : Enumeration Handling,Solutions:Always use valid constant values to resolve this issue and while trying to call this enum.valueOf() method always handle exception so that any exception happen then your program will not terminate.

package enm;

public class EnumTest {

	enum Month{JANNUARY,FEBRUARY,MARCH,APRIL,MAY,JUNE,JULY,AUGUST,SEPTEMBER,OCTOBER,NOVEMBER,DECEMBER};
	enum MonthDetail{
		JANNUARY("January",1),
		FEBRUARY("February",2),
		MARCH("March",3),
		APRIL("April",4),
		MAY("May",5),
		JUNE("June",6),
		JULY("July",7),
		AUGUST("August",8),
		SEPTEMBER("September",9),
		OCTOBER("October",10),
		NOVEMBER("November",11),
		DECEMBER("December",12);

		public String monthName="";
		public int index;

		//Constructor will always private
		private MonthDetail(String monthName,int index)
		{
			this.monthName=monthName;
			this.index=index;
		}
		//Method
		public void showMonthDetail()
		{
			System.out.println(this.index +" : "+this.monthName);
		}
	};
	public static void main(String[] args) {
		for(Month month:Month.values())
		{
	    //Add one because by default enum indexing start from 0
		System.out.println((month.ordinal()+1) +" : "+month.name());
		}
		//Every enum Class provide values method to get list of enums
		for(MonthDetail monthDetail:MonthDetail.values())
		{
			monthDetail.showMonthDetail();
		}

		try
		{
		MonthDetail mnth=MonthDetail.valueOf("Saturday");
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}

	}

}


Answer by Adelaide Fields

Special case of interpolating closure expressions,resolves the parent/child relationship for nested nodes, involving two other strategies:,Statements and expressions,Once you’ve written the class, using it is just a matter of redefining the groovydoc task:

// a standalone single line comment
println "hello" // a comment till the end of the line

Answer by Jessie Sharp

Hibernate supports the mapping of Java enums as basic value types in a number of different ways.,Hibernate supports three types of configurations within OSGi.,The mapping between the standard SQL Date/Time types and the supported Java 8 Date/Time class types looks as follows;,See the Hibernate Integrations Guide for more details on developing custom value type mappings.

create table Contact (
    id integer not null,
    first varchar(255),
    last varchar(255),
    middle varchar(255),
    notes varchar(255),
    starred boolean not null,
    website varchar(255),
    primary key (id)
)

Answer by Zara Frazier

To configure the check:
,To configure the check:,
To configure the default check:
,
To configure the default check:

int[] a = new int[]
{
  1,
  2,
  3,
};
        

Понравилась статья? Поделить с друзьями:
  • No such user ошибка
  • Nmi ошибка ожидания nc210
  • Non page area windows 10 ошибка
  • No efi system partition was found ошибка
  • No such file or directory python ошибка