Скотт Гу написал статью об этом один раз. Решение, которое он представил, состояло в том, чтобы использовать событие Pre-build для копирования правильной конфигурации на место в зависимости от выбранной конфигурации сборки.
Я также заметил, что уже есть аналогичный вопрос здесь, на SO.
Вы не можете принудительно заключить контракт с конструктором, используя интерфейс в Java. Наилучшее приближение, которое вы можете получить, - это определить интерфейс для фабрики с помощью метода create ()
, который принимает один HashMap
...
Также вы можете заменить интерфейс с абстрактным классом, для которого конструктору требуется HashMap
, который заставит подклассы выдавать один, но не больше (подклассы не обязательно будут иметь параметр HashMap).
Adding to the above answers, a constructor is an implementation detail. An interface defines a contract which describes how it behaves, not how it is assembled.
For this reason, you can't force an implementor to have a specific constructor. I think that whatever you're trying to do, an interface is not the way.
Update: This Annotation Processing Tool article describes how you can create an annotation and annotation processor which take effect at compile time and validate that a class has a no-arg constructor.
It can be adapted to work for a 1-argument constructor which takes a map instance.
To quote the article, its usage would be similar to:
@NoArgsConstructor
public abstract class NoArgsSuperClass {
public NoArgsSuperClass() {
}
}
// Passes
public class PublicNoArgsConstructor extends NoArgsSuperClass {
public PublicNoArgsConstructor() {
}
}
// Fails
public class NonPublicConstructor extends NoArgsSuperClass {
NonPublicConstructor() {
}
}
Вместо интерфейса вам нужно было бы создать абстрактный класс, объявить там конструктор, а затем любой класс, который наследует от него, должен будет вызвать базовый конструктор. Можно также сделать конструктор по умолчанию внутри базового класса закрытым.
Эндрю
Вы пытаетесь создать объект типа MyInterface посредством отражения?
Заводской интерфейс - гораздо более простая и лучшая альтернатива.
Определите заводской интерфейс (вы даже можете определить его как внутренний интерфейс в MyInterface. ).
interface MyInterface {
public static interface Factory {
create( HashMap< String, String > params );
}
}
Где бы ни создавались новые объекты MyInterface, убедитесь, что это делается только через MyInterface.Factory
.
По вопросу о дженериках. Из предоставленного вами кода MyInterface совсем не выглядит универсальным
В Java невозможно заставить класс реализовать конструктор с определенными типами аргументов. Зачем вам это нужно? Обычно это бесполезно.
Вы можете заставить неабстрактный класс реализовать определенный метод, заставив класс реализовать интерфейс или расширить абстрактный класс, в котором этот метод объявлен (но не определен) . Это полезно из-за полиморфизма; вы можете сделать переменную типа суперкласса ссылкой на экземпляр подкласса и вызвать метод:
interface Animal {
void makeSound(); }
}
class Dog implements Animal {
void makeSound() {
System.out.println("Woof!");
}
}
// Later:
Animal a = new Dog();
a.makeSound();
Теперь вы можете вызвать makeSound ()
, не зная, что a
относится к a Собака
; вы знаете, что объект, на который ссылается a
, имеет метод makeSound ()
, потому что он ' s объявлены в интерфейсе Animal
(и a
является Animal
).
В случае конструкторов вы никогда не вызываете конструктор полиморфно; вы всегда вызываете его, упоминая имя конкретного класса, который вы хотите создать. Из-за этого не очень полезно заставлять класс иметь конструктор с определенными параметрами.
Единственный случай, когда это может быть полезно, - это динамическое создание экземпляров классов через отражение. С помощью отражения вы можете узнать, какие конструкторы есть в классе, и вызвать один из них динамически. Затем вы можете вызвать исключение, если у класса нет конкретного конструктора, который вам нужен, но нет возможности проверить это во время компиляции.
вы никогда не вызываете конструктор полиморфно; вы всегда вызываете его, упоминая имя конкретного класса, который вы хотите создать. Из-за этого не очень полезно заставлять класс иметь конструктор с определенными параметрами.Единственный случай, когда это может быть полезно, - это динамическое создание экземпляров классов через отражение. С помощью отражения вы можете узнать, какие конструкторы есть в классе, и вызвать один из них динамически. Затем вы можете вызвать исключение, если у класса нет конкретного конструктора, который вам нужен, но нет возможности проверить это во время компиляции.
вы никогда не вызываете конструктор полиморфно; вы всегда вызываете его, упоминая имя конкретного класса, который вы хотите создать. Из-за этого не очень полезно заставлять класс иметь конструктор с определенными параметрами.Единственный случай, когда это может быть полезно, - это динамическое создание экземпляров классов через отражение. С помощью отражения вы можете узнать, какие конструкторы есть в классе, и вызвать один из них динамически. Затем вы можете вызвать исключение, если у класса нет конкретного конструктора, который вам нужен, но нет возможности проверить это во время компиляции.
Единственный случай, когда это может быть полезно, - это динамическое создание экземпляров классов через отражение. С помощью отражения вы можете узнать, какие конструкторы есть в классе, и вызвать один из них динамически. Затем вы можете вызвать исключение, если у класса нет конкретного конструктора, который вам нужен, но нет возможности проверить это во время компиляции.
Единственный случай, когда это может быть полезно, - это динамическое создание экземпляров классов через отражение. С помощью отражения вы можете узнать, какие конструкторы есть в классе, и вызвать один из них динамически. Затем вы можете вызвать исключение, если у класса нет конкретного конструктора, который вам нужен, но нет возможности проверить это во время компиляции.