Java 如何使用C10N库启用返回翻译字符串的类
我想使用来管理Java项目中的翻译,但我不知道如何使用它来支持类生成翻译字符串Java 如何使用C10N库启用返回翻译字符串的类,java,internationalization,c10n,Java,Internationalization,C10n,我想使用来管理Java项目中的翻译,但我不知道如何使用它来支持类生成翻译字符串 请考虑以下单个语言示例: public interface Pet { public String getBreed(); } public class Dog implements Pet { private String breed; public Dog(String breed) { this.breed = breed; } public St
请考虑以下单个语言示例:
public interface Pet {
public String getBreed();
}
public class Dog implements Pet {
private String breed;
public Dog(String breed) {
this.breed = breed;
}
public String getBreed() {
return this.breed;
}
}
然后,我想更改以前的实现以支持i18n
因此,我可以使用C10N声明一些翻译:
public interface DogBreeds{
@En("dalmatian")
@It("dalmata")
String dalmatian();
@En("poodle")
@It("barboncino")
String poodle();
}
现在,我想在类中使用这些方法之一来返回翻译后的字符串。其思想是以某种方式将方法传递给类,然后从类的方法调用它。
换句话说,该类应该能够基于当前语言环境返回正确的翻译,而当前语言环境在运行时可能会发生变化
public class Dog implements Pet {
public Dog(??) {
// the class should receive all the translations
// related to a specific breed
}
public String getBreed() {
// here I want to return the correct breed name translation,
// based on the current locale
return ??;
}
}
Dog
类不应直接访问dogbrides
接口。例如,Dog
可能是库的一部分,而dogbrides
可能在主项目中声明
Dog
类不应该只保存基于当前区域设置的一个翻译,而是保存所有可用的翻译,以便在区域设置更改时返回正确的翻译
这是一种干净的方法吗?如果没有,还有什么选择?我会尝试:
public class Dog implements Pet {
private static final DogBreeds BREEDS = C10N.get(DogBreeds.class);
public Dog() {
// no need to pass the translations to the constructor
}
public String getBreed() {
// Since you're wanting to specify a message key dynamically,
// you need to use getString instead of BREEDS.poodle().
return BREEDS.getString(myBreed);
}
}
如果您想将
dogbride
(主项目)和Dog
(库)分开,那么考虑到您的主项目引用库(而不是相反),您需要在库中引入一些其他共享接口,比如说,BreedNameProvider
public interface BreedNameProvider{
String dalmatian();
String poodle();
}
然后您可以将其传递给Dog
类构造函数:
public class Dog implements Pet {
private final BreedNameProvider bnp;
public Dog(BreedNameProvider bnp) {
this.bnp = bnp;
}
public String getBreed() {
return bnp.poodle();
}
}
BreedNameProvider
的实现可以在主项目中声明,因此可以安全地访问dogbrides
接口
编辑:您可以使用更通用的BreedNameProvider
,在运行时通过工作区域设置切换返回所需的翻译:
//Declared in your library
public interface BreedNameProvider{
String getBreedName();
}
public class Dog implements Pet {
private final BreedNameProvider bnp;
public Dog(BreedNameProvider bnp) {
this.bnp = bnp;
}
public String getBreed() {
return bnp.getBreedName();
}
}
在主项目中,当实例化不同类型的狗时
只需传递BreedNameProvider
的实现,该实现将返回所需品种的本地化字符串:
public class MainProject{
private static final DogBreeds breeds = C10N.get(DogBreeds.class);
public void createDogs(){
//Create a poodle
Dog poodle = new Dog(new BreedNameProvider(){
@Override
public String getBreedName(){
return breeds.poodle();
}
});
//Create dalmatian
Dog dalmatian = new Dog(new BreedNameProvider(){
@Override
public String getBreedName(){
return breeds.dalmatian();
}
});
}
}
实际上,这相当于将方法“传递”给Dog
构造函数,这正是您在原始帖子中要求的。在java中,这几乎是在不牺牲编译时安全性的情况下实现这一点的唯一方法
实现BreedNameProvider
的另一种方法如下:
public class MainProject{
private static final DogBreeds breeds = C10N.get(DogBreeds.class);
class CodeBreedNameProvider implements BreedNameProvider{
private final String breedCode;
CodeBreedNameProvider(String breedCode){
this.breedCode = breedCode;
}
@Override
public String getBreedName(){
switch(breedCode){
case "poodle": return breeds.poodle();
case "dalmatian": return breeds.dalmatian();
//... more if needed
}
return "unknown breed code " + breedCode;
}
}
public void createDogs(){
//Create a poodle
Dog poodle = new Dog(new CodeBreedNameProvider("poodle"));
//Create dalmatian
Dog dalmatian = new Dog(new CodeBreedNameProvider("dalmatian"));
}
}
你看过主页上的文档了吗?它们明确地显示了该做什么。@chrylis是的,我做了,但不是我的问题不清楚,就是我不理解文档。我会再写一些细节。你的要求毫无意义。C10N的整个要点是类型安全的消息绑定,它要求您指定要从中查找的类型。如果你不想要类型安全,那么完全跳过C10N,只使用常规的消息资源包。请参阅我的编辑:类
狗
不应该直接引用狗种
接口可能我的问题不够清楚。我需要做的是实例化一只Dog
,它从dalmatian()
方法中获取品种名称,另一只使用poodle()
(依此类推)。所以我不想传递整个界面,只想传递一个特定的翻译。如果这毫无意义,还有其他选择吗?例如,声明多个C10N
接口并传递一个特定的接口…如果您在狗的实例化之前知道品种名称,您不能将品种名称传递给其构造器吗?如果直到运行时才知道名称,可以让更通用的BreedNameProvider#getBreedName()执行逻辑并返回适当的值。或者可能我没有理解这个问题,对吗?我不想根据当前区域设置只向类传递一个字符串。Dog
类应该能够基于当前区域设置返回犬种名称,即使区域设置在运行时发生更改。我更新了我的问题,我希望它现在更清楚一点。请看我的答案中的编辑。希望这能把事情弄清楚。