Избегайте множественного создания одноэлементного изображения с использованием отражения [duplicate]

Буквально самый простой способ исправить NullReferenceExeption имеет два пути. Если у вас есть GameObject, например, с прикрепленным скриптом и переменной с именем rb (rigidbody), эта переменная начнет пустую, когда вы начнете игру. Вот почему вы получаете NullReferenceExeption, потому что на компьютере нет данных, хранящихся в этой переменной.

В качестве примера я буду использовать переменную RigidBody. Мы можем добавить данные действительно легко на самом деле несколькими способами:

  1. Добавить RigidBody к вашему объекту с помощью AddComponent> Физика> Rigidbody Затем зайдите в свой скрипт и введите rb = GetComponent<Rigidbody>();. Эта строка кода работает лучше всего под ваши функции Start() или Awake().
  2. Вы можете добавить компонент программно и назначить переменную одновременно с одной строкой кода: rb = AddComponent<RigidBody>();

Дальнейшие заметки: если вы хотите, чтобы единство добавлялось компонент для вашего объекта, и вы, возможно, забыли добавить его, вы можете ввести [RequireComponent(typeof(RigidBody))] над объявлением класса (пробел ниже всех ваших приложений). Наслаждайтесь и получайте удовольствие от игр!

24
задан Talha Ahmed Khan 9 August 2011 в 10:58
поделиться

10 ответов

Попробуйте создать свой публичный конструктор

private Singleton() {
    if( Singleton.singleton != null ) {
        throw new InstantiationError( "Creating of this object is not allowed." );
    }
}
46
ответ дан Dave G 24 August 2018 в 01:30
поделиться

Perfect Singleton Class, который может избежать создания экземпляра во время сериализации, клонирования и отражения.

import java.io.Serializable;

public class Singleton implements Cloneable, Serializable {

    private static final long serialVersionUID = 1L;
    private static volatile Singleton instance;

    private Singleton() {
        if (instance != null) {
            throw new InstantiationError("Error creating class");
        }
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {

                if (instance == null) {
                    return new Singleton();
                }
            }
        }
        return null;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }

    Object readResolve() {
        return Singleton.getInstance();
    }

}
0
ответ дан ABHAY JOHRI 24 August 2018 в 01:30
поделиться

Определите синглтон следующим образом:

public enum Singleton {
    INSTANCE
}
15
ответ дан Arne 24 August 2018 в 01:30
поделиться
Here Reflection not work     

    package com.singleton.nonbreakable;

        import java.io.FileInputStream;
        import java.io.FileOutputStream;
        import java.io.ObjectInputStream;
        import java.io.ObjectOutputStream;
        import java.lang.reflect.Constructor;

        class FullySingletonClass {

            public static void main(String[] args) {

                SingletonImpl object1 = SingletonImpl.getInstance();
                System.out.println("Object1:" + object1);

                try {
                    FileOutputStream fos = new FileOutputStream("abc.txt");
                    ObjectOutputStream oos = new ObjectOutputStream(fos);
                    oos.writeObject(object1);

                    FileInputStream fis = new FileInputStream("abc.txt");
                    ObjectInputStream ois = new ObjectInputStream(fis);
                    SingletonImpl object2 = (SingletonImpl) ois.readObject();
                    System.out.println("Object2" + object2);

                } catch (Exception e) {
                    // TODO: handle exception
                }
                try {
                    Constructor[] constructors = SingletonImpl.class.getDeclaredConstructors();
                    for (Constructor constructor : constructors) {
                        // Below code will not destroy the singleton pattern
                        constructor.setAccessible(true);
                        SingletonImpl Object3 = (SingletonImpl) constructor.newInstance();
                        System.out.println("Object3:" + Object3);
                        break;
                    }
                } catch (Exception ew) {

                }

            }
        }


    package com.singleton.nonbreakable;

    import java.io.Serializable;

    class SingletonImpl implements Cloneable, Serializable {

        public static SingletonImpl singleInstance = null;

        private static class SingletonHolder {
            public static SingletonImpl getInstance() {
                if (null == singleInstance) {
                    singleInstance = new SingletonImpl();
                }
                return singleInstance;
            }
        }

        private SingletonImpl() {

        }

        @Override
        protected Object clone() throws CloneNotSupportedException {
            return singleInstance;
        };

        public Object readResolve() {
            System.out.println("Executing readResolve again");
            return SingletonImpl.getInstance(); // FIXME
        }

        public static SingletonImpl getInstance() {

            return SingletonHolder.getInstance();
        }

    }

    Output : 
    Object1:com.singleton.nonbreakable.SingletonImpl@15db9742
    Executing readResolve again
    Object2com.singleton.nonbreakable.SingletonImpl@15db9742
1
ответ дан Ashish Agrawal Yodlee 24 August 2018 в 01:30
поделиться
private Singleton() { 
    if (Singleton.singleton != null) {
        throw new RuntimeException("Can't instantiate singleton twice");
    }
}

Еще одна вещь, которую вы должны посмотреть - это метод readResolve(..), потому что ваш класс реализует Serialiable. Там вы должны вернуть существующий экземпляр.

Но самый простой способ использования синглонов - перечислить - вы не беспокоитесь об этом.

10
ответ дан Bozho 24 August 2018 в 01:30
поделиться

Как насчет проверки в конструкторе:

private Singleton() {
    if (singleton != null) {
        throw new IllegalStateException("Singleton already constructed");
    }
}

Конечно, это не может действительно остановить его - если кто-то возится с рефлексией для доступа к закрытым членам, они может быть в состоянии задать поле для нулевого значения. Вы должны спросить себя, что именно вы пытаетесь предотвратить, и как это стоит.

(EDIT: Как отметил Божо, окончательные поля могут быть недоступны даже при отражении. удивился, если есть некоторые способы сделать это через JNI и т. д., хотя ... если вы дадите людям достаточно доступа, они смогут делать почти все ...)

11
ответ дан Jon Skeet 24 August 2018 в 01:30
поделиться

В качестве альтернативы синглтону вы можете взглянуть на шаблон моностата . Затем создание экземпляра вашего класса больше не является проблемой, и вам не нужно беспокоиться о любом перечисленных вами сценариях.

В шаблоне monostate все поля в вашем классе static. Это означает, что все экземпляры класса имеют одно и то же состояние, как с одним синглоном. Более того, этот факт прозрачен для вызывающих; им не нужно знать о специальных методах, таких как getInstance, они просто создают экземпляры и работают с ними.

Но, как и при использовании singleton, это форма скрытого глобального состояния; который очень плохой .

1
ответ дан Jordão 24 August 2018 в 01:30
поделиться

Просто отметим, что с Java 8 и в соответствии с моей проверкой невозможно создать экземпляр Singleton через Reflections, если у него есть частный конструктор.

Вы получите это исключение:

Exception in thread "main" java.lang.IllegalAccessException: Class com.s.Main can not access a member of class com.s.SingletonInstance with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at com.s.Main.main(Main.java:6)
0
ответ дан olive_tree 24 August 2018 в 01:30
поделиться

Чтобы преодолеть проблему, вызванную рефлексией, используются перечисления, поскольку java обеспечивает внутренне, что значение перечисления создается только один раз. Поскольку java Enums доступны по всему миру, их можно использовать для одиночных игр. Его единственный недостаток заключается в том, что он не является гибким, и это не допускает ленивой инициализации.

public enum Singleton {
 INSTANCE
}

public class ReflectionTest 
{

    public static void main(String[] args)
    {
        Singleton instance1 = Singleton.INSTANCE;
        Singleton instance2 = Singleton.INSTANCE;
    System.out.println("instance1 hashcode- "
                                      + instance1.hashCode());
        System.out.println("instance2 hashcode- "
                                      + instance2.hashCode());
    }
}

JVM обрабатывает создание и вызов конструкторов enum внутри. Поскольку перечисления не дают определение своего конструктора программе, мы не можем получить к ним доступ также с помощью Reflection.

Подробнее см. В сообщении.

0
ответ дан Swati Gour 24 August 2018 в 01:30
поделиться

I Thing Ниже код будет работать.

class Test {

    static private Test t = null;
    static {
        t = new Test();
    }

    private Test(){}

    public static Test getT() {
        return t;
    }

    public String helloMethod() {
        return "Singleton Design Pattern";
    }
}


public class MethodMain {

    public static void main(String[] args) {
        Test t = Test.getT();
        System.out.println(t.helloMethod());
    }
}

output: Singleton Design Pattern

1
ответ дан Vojtech Ruzicka 24 August 2018 в 01:30
поделиться
Другие вопросы по тегам:

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