2015-07-25 22 views
6

Bazı nedenlerle, sınıfına başka bir sınıf Z, bir Y, bir ClassCastException atar. Bu sınıf X diğer sınıfını Y uzanır gibi görerek, bana yanlış geliyor. sınıf X onu genişletir Y bile X olsa artığını edilemedi neden özel bir sebebi var mı?X Y uzanır halde bir sınıf "Y" için bir sınıf "X" dökme olmaz mı?

Y:

public abstract class Y { 
    /** 
     * Called when the extension is enabled. 
     */ 
    public void onEnable() { 
    } 
} 

X:

public class X extends Y { 
    @Override 
    public void onEnable() { 
     // Extension specific code. 
    } 
} 

Z: (Bu kod t

kullanım için aşağıdaki kod bakınız Nerede ClassCastException kaynaklanır kod.) loader.loadClass(description.getMain()).newInstance();X yeni bir örneğini oluşturmak için bilinir

public class Z { 
    private boolean loadExtension(ExtensionDescription description) { 
     try { 
      URLClassLoader loader = new ExtensionClassLoader(new URL[]{description.getFile().toURI().toURL()}); 
      Y y = (Y) loader.loadClass(description.getMain()).newInstance(); 
     } catch (Throwable t) {} 
    } 
} 

, o zaman Y neden bir ClassCastException için döküm neden?

bir Custom ClassLoader oluşturun, örneğin:

+0

iki farklı sınıf yükleyiciler –

+3

tek nedeni olurdu Ben bunu düşünüyorum. Z sınıfı kendi programında çalışırken, X sınıfı, Z sınıfının çalıştırıldığı program tarafından çalıştırılan bir programda çalışmaktadır. (Bu mantıklıysa, oldukça karmaşıktır.) Ana programın sınıf yükleyicisini nasıl alacağımı anlamanız gerekebilir. – TheCodingFrog

+0

@TheCodingFrog tarafından yüklenen X ve Y aslında hiçbir kesin sorun olabilir Yani nerede description.getMain() '. –

cevap

4

Sadece ileri göstermek için aşağıda bir örnek olduğunu Aşağıda (here kopyalanan)

package com.dd; 

import java.io.BufferedInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.util.HashMap; 
import java.util.Map; 

public class CustomClassLoader extends ClassLoader { 

    /** 
    * The HashMap where the classes will be cached 
    */ 
    private Map<String, Class<?>> classes = new HashMap<String, Class<?>>(); 

    @Override 
    public String toString() { 
     return CustomClassLoader.class.getName(); 
    } 

    @Override 
    protected Class<?> findClass(String name) throws ClassNotFoundException { 

     if (classes.containsKey(name)) { 
      return classes.get(name); 
     } 

     byte[] classData; 

     try { 
      classData = loadClassData(name); 
     } catch (IOException e) { 
      throw new ClassNotFoundException("Class [" + name 
        + "] could not be found", e); 
     } 

     Class<?> c = defineClass(name, classData, 0, classData.length); 
     resolveClass(c); 
     classes.put(name, c); 

     return c; 
    } 

    /** 
    * Load the class file into byte array 
    * 
    * @param name 
    *   The name of the class e.g. com.codeslices.test.TestClass} 
    * @return The class file as byte array 
    * @throws IOException 
    */ 
    private byte[] loadClassData(String name) throws IOException { 
     BufferedInputStream in = new BufferedInputStream(
       ClassLoader.getSystemResourceAsStream(name.replace(".", "/") 
         + ".class")); 
     ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     int i; 

     while ((i = in.read()) != -1) { 
      out.write(i); 
     } 

     in.close(); 
     byte[] classData = out.toByteArray(); 
     out.close(); 

     return classData; 
    } 
} 

Ve burada sınıf Z

package com.dd; 

import java.lang.reflect.InvocationTargetException; 

public class Z { 

    public static void main(String[] args) throws ClassNotFoundException, 
      InstantiationException, IllegalAccessException, 
      NoSuchMethodException, SecurityException, IllegalArgumentException, 
      InvocationTargetException { 

     CustomClassLoader loader = new CustomClassLoader(); 
     Class<?> c1 = loader.findClass("com.dd.X"); 

     System.out.println("Classloader:: "+ X.class.getClassLoader()); 
     System.out.println("Classloader:: "+ loader.findClass("com.dd.X").getClassLoader()); 

     X x = (X)c1.newInstance(); 
    } 
} 

var Ve burada çıkış var: (`X.class == loader.loadClass kontrol edin programında

Classloader:: [email protected] 
Classloader:: com.dd.CustomClassLoader 
Exception in thread "main" java.lang.ClassCastException: com.dd.X cannot be cast to com.dd.X 
    at com.dd.Z.main(Z.java:18) 
+0

Teşekkürler. Şimdi sorunu anlıyorum. Anlamadığım şey, bunun nasıl düzeltileceği. Burada iki farklı sınıf yükleyicinin çalıştığı gerçeğini anlamak mümkün değil. Bunun nedeni, burada olan şeyin ardındaki fikir: bir programın bir eklenti sistemi var ... bir eklenti sistemi olan bir eklenti yükler ve ikincil eklenti sistemi bir eklenti yüklemeye çalışıyor.Bunun ana sınıf yükleyicisi ve burada hatam eklenti ClassLoader arasındaki çatışma olduğunu varsayalım. olduğu sonucuna Yani, aslında düzeltmek ya da ben programın mantığını yeniden düşünmek gerekiyor herhangi bir yolu var mı? –

+2

ebeveynlerinizden ayarlamak ve uygulamanızda kullanmak için gereken tüm türleri (özellikle dökme) oradan yüklü olduğundan emin olun bu yüzden, varsayılan olarak her sınıf yükleyici da üst öğesini sorar bir sınıf bulma önce. – eckes

+0

@eckes Tamam. Teşekkürler! Bunun olduğundan emin olmak için neler yapabileceğimi göreceğim. –

İlgili konular