Как я могу получить доступ к частному конструктору класса? - PullRequest
63 голосов
/ 08 апреля 2010

Я разработчик Java.В одном из интервью мне задали вопрос о частных конструкторах:

Можете ли вы получить доступ к частному конструктору класса и создать его экземпляр?

Я ответил «Нет», но былнеправильно.

Можете ли вы объяснить, почему я ошибался, и привести пример создания объекта с помощью частного конструктора?

Ответы [ 18 ]

0 голосов
/ 10 января 2019

Я пытался, как это работает. Дайте мне предложение, если я ошибаюсь.

import java.lang.reflect.Constructor;

class TestCon {
private TestCon() {
    System.out.println("default constructor....");
}

public void testMethod() {
    System.out.println("method executed.");
  }
}

class TestPrivateConstructor {

public static void main(String[] args) {
    try {
        Class testConClass = TestCon.class;
        System.out.println(testConClass.getSimpleName());

        Constructor[] constructors =    testConClass.getDeclaredConstructors();
        constructors[0].setAccessible(true);
        TestCon testObj = (TestCon) constructors[0].newInstance();
        //we can call method also..
        testObj.testMethod();
    } catch (Exception e) {
        e.printStackTrace();
    }

}
}
0 голосов
/ 09 января 2019

Мы не можем получить доступ к приватному конструктору вне класса, но с помощью Java Reflection API мы можем получить доступ к приватному конструктору. Пожалуйста, найдите ниже код:

public class Test{
    private Test()
    System.out.println("Private Constructor called");
}
}


public class PrivateConsTest{
    public void accessPrivateCons(Test test){

        Field[] fields = test.getClass().getDeclaredFields();

        for (Field field : fields) {
            if (Modifier.isPrivate(field.getModifiers())) {
                field.setAccessible(true);
                System.out.println(field.getName()+" : "+field.get(test));
            }
        }
    }
}

Если вы используете Spring IoC, контейнер Spring также создает и внедряет объект класса, имеющий приватный конструктор.

0 голосов
/ 08 января 2019

Надеюсь, этот пример может вам помочь:

package MyPackage;

import java.lang.reflect.Constructor;

/**
 * @author Niravdas
 */

class ClassWithPrivateConstructor {

    private ClassWithPrivateConstructor() {
        System.out.println("private Constructor Called");
    }

}
public class InvokePrivateConstructor 
{
     public static void main(String[] args) {
        try
        {
           Class ref = Class.forName("MyPackage.ClassWithPrivateConstructor");
           Constructor<?> con = ref.getDeclaredConstructor();
           con.setAccessible(true);
           ClassWithPrivateConstructor obj = (ClassWithPrivateConstructor) con.newInstance(null);
       }catch(Exception e){
           e.printStackTrace();
       }
    }

}

Вывод: закрытый конструктор Called

0 голосов
/ 25 февраля 2017

Основная предпосылка наличия частного конструктора состоит в том, что наличие частного конструктора ограничивает доступ к коду, отличному от кода собственного класса, от создания объектов этого класса.

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

 Class A{
private A(){
}
private static createObj(){
return new A();
}

Class B{
public static void main(String[]args){
A a=A.createObj();
}}

Таким образом, чтобы создать объект этого класса, другой класс должен использовать статические методы.

Какой смысл иметь статический метод, когда мы делаем конструктор закрытым?

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

 public static MySingleTon getInstance(){
    if(myObj == null){
        myObj = new MySingleTon();
    }
    return myObj;
}
0 голосов
/ 30 июня 2016

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

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

class Deny {
  private Deny() {
    System.out.format("Deny constructor%n");
  }
}

public class ConstructorTroubleAccess {
  public static void main(String... args) {
    try {
      Constructor c = Deny.class.getDeclaredConstructor();
      // c.setAccessible(true); // solution
      c.newInstance();

      // production code should handle these exceptions more gracefully
    } catch (InvocationTargetException x) {
      x.printStackTrace();
    } catch (NoSuchMethodException x) {
      x.printStackTrace();
    } catch (InstantiationException x) {
      x.printStackTrace();
    } catch (IllegalAccessException x) {
      x.printStackTrace();
    }
  }
}
0 голосов
/ 11 декабря 2015

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

ClassWithPrivateConstructor.getObj().printsomething();

это определенно будет работать, потому что я уже тестировал

0 голосов
/ 08 апреля 2010

Посмотрите на рисунок синглтона. Он использует приватный конструктор.

0 голосов
/ 09 апреля 2010

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

...