Продолжите: управление экземпляром в Java без [закрытого] перечисления

В случае установки Xampp.

В моем случае перейдите к вашей установке xampp и папке mysql: C: \ xampp \ mysql

Запустите файл "resetroot.bat" из cmd или explorer.

Моя установка начала работать !!!

6
задан Community 23 May 2017 в 11:50
поделиться

2 ответа

Герметично ли это решение?

Нет. (Хотя этого может быть достаточно, в зависимости от того, как и где используется код.)

В Правило 77: Например, управление, предпочитайте типы перечислений, а не readResolve ( Эффективная Java, 2-е изд ), Блох демонстрирует, как злоумышленник может заставить такой класс, как ваш, вернуть любое значение. Атака основана на ручном вводе байтов и возможности запустить код на цели (поэтому ваш код может представлять угрозу безопасности при использовании в изолированной среде, некоторых случаях RMI и т. Д.). Я не знаю, единственное ли это нападение - оно единственное упомянутое. Решение состоит в том, чтобы объявить все поля временными, но тогда у вас возникнет проблема, как сохранить значение.

Вы можете решить эти проблемы, используя шаблон прокси-сервера сериализации (элемент 78 в книга - там ' Это причина, по которой каждый Java-программист, прочитавший это, рекомендует это).

public final class Thing implements Serializable {
  private static final long serialVersionUID = 1L;
  private static final Thing[] INSTANCES = new Thing[2];
  private static int NEXT_ORDINAL = 0;

  public static final Thing INSTANCE0 = new Thing(
      "whatever0");
  public static final Thing INSTANCE1 = new Thing(
      "whatever1");

  private transient final String someState;

  public String someMethod() {
    return someState;
  }

  private final int ordinal;

  private Thing(String someState) {
    this.someState = someState;
    ordinal = NEXT_ORDINAL++;
    INSTANCES[ordinal] = this;
  }

  private Object writeReplace() {
    return new ThingProxy(this);
  }

  private void readObject(ObjectInputStream stream)
      throws InvalidObjectException {
    throw new InvalidObjectException("Proxy required");
  }

  private static class ThingProxy implements Serializable {
    private static final long serialVersionUID = 1L;
    private final int ordinal;

    private ThingProxy(Thing t) {
      ordinal = t.ordinal;
    }

    private Object readResolve()
        throws ObjectStreamException {
      return INSTANCES[ordinal];
    }

  }

}

Хотя, как и при копировании чего-либо, связанного с безопасностью, из Интернета, будьте осторожны. Я ни в коем случае не эксперт.

8
ответ дан 10 December 2019 в 02:52
поделиться

в этом коде все еще отсутствуют некоторые интересные особенности Enum:

  • отсутствует "values ​​()" как Итератор по всем значениям перечисления
  • все еще отсутствует Диапазон Итератор
  • не может использоваться в коммутаторе

Пример

public final class Day implements Serializable {

    private static final long serialVersionUID = 1L;
    private static Day[] instances = new Day[7];
    public static final Day MONDAY = new Day("Monday");
    public static final Day TUESDAY = new Day("Tuesday");
    public static final Day WEDNESDAY = new Day("Wednesday");
    public static final Day THURSDAY = new Day("Thursday");
    public static final Day FRIDAY = new Day("Friday");
    public static final Day SATURDAY = new Day("Saturday");
    public static final Day SUNDAY = new Day("Sunday");
    private static int nextOrdinal = 0;
    private transient final String name;
    private final int ordinal;

    private Day(String aName) {
        this.name = aName;
        this.ordinal = nextOrdinal++;
        instances[this.ordinal] = this;
    }

    private Object readResolve() throws ObjectStreamException {
        return instances[this.ordinal];
    }

    public String toString() {
        return name;
    }

    public boolean equals(Object obj) {
        return obj instanceof Day && ((Day) obj).ordinal == ordinal;
    }

    public int hashCode() {
        return name.hashCode();
    }

    public static Iterator values() {
        return new Iterator() {

            private int i = 0;

            public boolean hasNext() {
                return i < instances.length;
            }

            public Object next() {
                return instances[i++];
            }

            public void remove() {
                throw new UnsupportedOperationException("Not supported.");
            }
        };
    }

    public static Iterator range(final Day from, final Day to) {
        return new Iterator() {

            private int i = from.ordinal;

            public boolean hasNext() {
                return i <= to.ordinal;
            }

            public Object next() {
                return instances[i++];
            }

            public void remove() {
                throw new UnsupportedOperationException("Not supported.");
            }
        };
    }

    public static void main(String[] args) {
        Iterator week = Day.values();

        while (week.hasNext()) {
            System.out.println(week.next());
        }

        Iterator weekEnd = Day.range(SATURDAY, SUNDAY);

        while (weekEnd.hasNext()) {
            System.out.println(weekEnd.next());
        }
    }
}
1
ответ дан 10 December 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: