2016-01-22 4 views
0

Я пытаюсь работать с этим перечислением и добавлять новые материалы. Все, что еще не удалено, имеет жесткие зависимости в другом месте, даже если это все равно, это почти ограничение по байтам java в соответствии с автором модов, поэтому в любом случае на самом деле нет много места для работы.Создание и переопределение объектов Java Enum в Runtime [GregTech/minecraft]

GregoriousT упоминается «Есть один способ.

Enum мы говорим о: http://pastebin.com/g0aJ2Qjd

Так что я просто спросить, как бы я идти об этом?

Это то, что моя текущая попытка бросает [FML]: Variable m:1|newInstance|public java.lang.Object sun.reflect.DelegatingConstructorAccessorImpl.newInstance(java.lang.Object[]) throws java.lang.InstantiationException,java.lang.IllegalArgumentException,java.lang.reflect.InvocationTargetException|false , прежде чем клиент выйдет из строя. (Log код удален для легкого чтения)

Текущая попытка:

public class MaterialsNew { 

public static void getGregMaterials() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, SecurityException{ 
Utils.LOG_WARNING("Stepping through the process of Greg's materials."); 

    Constructor<?> con = Materials.class.getDeclaredConstructors()[0]; 
java.lang.reflect.Method[] methods = con.getClass().getDeclaredMethods(); 
for (java.lang.reflect.Method m1 : methods) { 
    if (m1.getName().equals("acquireConstructorAccessor")) { 
     m1.setAccessible(true); 
     m1.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); 
Materials v = (Materials) m.invoke(ca, new Object[] { new Object[] { "NEWMATERIAL", Integer.MAX_VALUE } }); 
System.out.println(v.getClass() + ":" + v.name() + ":" + v.ordinal());}} 

помощь или предложения оценили, они ребята более на кузнечной IRC не были действительно уверены, либо.

+0

Я сомневаюсь, что вы можете сделать это, используя простой Reflection. Но вопрос в том, действительно ли вам нужно взломать тип «enum» или вам просто нужна реализация интерфейсов «IColorModulationContainer» и «ISubTagContainer»? – Holger

+0

Кроме того, вы должны отформатировать исходный код читаемым способом и прекратить загрязнение кода с помощью операторов протоколирования между каждым оператором. Это очень трудно читать. – Holger

+0

Если это не содержится в списке материалов, это бесполезный код, который не загружается и даже не обрабатывается. Именно поэтому изменение его во время выполнения - это единственный реальный вариант AFAIK. Реально, хотя, считая того, кто это сделал ранее, был/был одним из основных программистов Forge, я не ожидал, что это будет в моих возможностях вообще. Я знаю, что это не стандартный случай использования вообще, и он идет против точки перечисления, но иногда вам просто нужно расширять работу кого-то. (Мне было приятно попробовать, так почему бы и нет) – Draknyte1

ответ

1

JVM должны предотвращать такие подлые дела enum. Таким образом, вы должны либо использовать недостаток, который вскоре может быть разрешен или взломать настолько глубоко в JRE, что малейшее изменение может нарушить его.

Вот трюк, который работает с текущей JRE в Oracle 8, возможно, JRE 7, а также, и это удивительно просто:

import java.lang.invoke.MethodHandle; 
import java.lang.invoke.MethodHandles; 
import java.lang.reflect.Constructor; 
import java.util.EnumSet; 

public class EnumHack { 
    public static void main(String[] args) throws Throwable { 
     Constructor<Thread.State> c 
      = Thread.State.class.getDeclaredConstructor(String.class, int.class); 
     c.setAccessible(true); 
     MethodHandle h=MethodHandles.lookup().unreflectConstructor(c); 
     Thread.State state=(Thread.State)h.invokeExact("FLYING", 42); 
     System.out.println("created Thread.State "+state+"("+state.ordinal()+')'); 
     System.out.println(EnumSet.allOf(Thread.State.class).contains(state)); 
    } 
} 

Но не ожидаем, что это решение упорствовать ...

 Смежные вопросы

  • Нет связанных вопросов^_^