Контейнер с несколькими экземплярами фляги, имеющей класс со статическими переменными - PullRequest
0 голосов
/ 14 сентября 2011

У меня есть класс A, содержащий статический / одноэлементный член с именем b.

Этот класс включен в jar X, который появляется в нескольких местах.

Мой вопрос:

  1. Есть ли в контейнере, имеющем эту кодовую базу, несколько копий баночки X (и, следовательно, класса A)?У меня есть назначение Ab = 10; член b, чья копия A получит назначение?В настоящее время у меня есть проблема, которая, кажется, возникает из-за этого сценария, когда даже после установки статической переменной некоторого значения, я получаю нулевое значение в другой части кода, которая ее читает.Каков правильный «шаблон», чтобы следовать, чтобы избежать / преодолеть эту проблему (при условии, что мой диагноз правильный)?

-KS

1 Ответ

0 голосов
/ 14 сентября 2011

Вот небольшая идея того, что происходит с различными ClassLoader s:

package test;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;

public class StaticMemberTest {
    public static int count = 0;

    public static void main(String[] args) throws Exception {
        // my .class files are in bin, relative to where I run the test from
        File f = new File("./bin");
        URL u = f.toURL();

        ClassLoader classLoader1 = new URLClassLoader(new URL[] { u }, null);
        ClassLoader classLoader2 = new URLClassLoader(new URL[] { u }, null);

        Class class1 = classLoader1.loadClass("test.StaticMemberTest");
        System.out.println("class1=" + class1);
        System.out.println("class1.count=" + class1.getDeclaredField("count").get(null));

        Class class2 = classLoader2.loadClass("test.StaticMemberTest");
        System.out.println("class2=" + class2);
        System.out.println("class2.count=" + class2.getDeclaredField("count").get(null));

        class1.getDeclaredField("count").set(null, new Integer(99));

        System.out.println("class1.count=" + class1.getDeclaredField("count").get(null));
        System.out.println("class2.count=" + class2.getDeclaredField("count").get(null));

        System.out.println("class1.isAssignableFrom(class2)=" + class1.isAssignableFrom(class2));
        System.out.println("class2.isAssignableFrom(class1)=" + class2.isAssignableFrom(class1));

        Object ob1 = class1.newInstance();
        System.out.println("ob1=" + ob1);

        StaticMemberTest test = (StaticMemberTest) ob1;
    }
}

И выводом

class1=class test.StaticMemberTest
class1.count=0
class2=class test.StaticMemberTest
class2.count=0
class1.count=99
class2.count=0
class1.isAssignableFrom(class2)=false
class2.isAssignableFrom(class1)=false
ob1=test.StaticMemberTest@35ce36
Exception in thread "main" java.lang.ClassCastException: test.StaticMemberTest
    at test.StaticMemberTest.main(StaticMemberTest.java:37)

Таким образом, вы можете видеть, что имена классовто же самое, и оба отсчета начинаются с нуля.Но вы можете установить значения статических переменных независимо друг от друга.

Кроме того, тесты isAssignableFrom показывают, что классы не совпадают в том, что касается JVM.

И наконец, когда япопробуйте бросок, который должен работать, он терпит неудачу.Потому что ClassLoader, который загрузил class1, был , а не в той же иерархии ClassLoader, что и ClassLoader, который использовался для запуска теста.Поэтому созданный им объект ob1 не совместим с Class самого теста.

...