如何在Java中传递一个types作为方法参数

在Java中,如何将types作为parameter passing(或声明为variables)?

我不想传递一个types的实例 ,但types本身(如int,String等)。

在C#中,我可以这样做:

private void foo(Type t) { if (t == typeof(String)) { ... } else if (t == typeof(int)) { ... } } private void bar() { foo(typeof(String)); } 

没有传递typest的实例 Java中有没有办法?
或者我必须使用我自己的int常量或枚举?
或者,还有更好的方法?

编辑:这是foo的要求:
基于typest,它会生成一个不同的简短xmlstring。
if / else中的代码将非常小(一行或两行),并将使用一些私有类variables。

你可以传入一个Class<T>

 private void foo(Class<?> cls) { if (cls == String.class) { ... } else if (cls == int.class) { ... } } private void bar() { foo(String.class); } 

更新 :OOP方式取决于function要求。 最好的办法是定义foo()的接口和两个实现foo()具体实现,然后在你手头的实现上调用foo() 。 另一种方式可能是一个Map<Class<?>, Action> ,你可以通过actions.get(cls)调用。 这很容易与一个接口和具体实现相结合: actions.get(cls).foo()

我有一个类似的问题,所以我在下面编写了一个完整的可运行的答案。 我需要做的是将一个类(C)传递给一个不相关类的对象(O),并且当我请求它时,该对象(O)将(C)类的新对象发回给我。

下面的例子显示了这是如何完成的。 有一个MagicGun类可以加载子弹类(Pebble,Bullet或NuclearMissle)的任何子types。 有趣的是你加载子弹的子types,但不是这种types的实际对象。 MagicGun在拍摄时创build实际的物体。

输出

 You've annoyed the target! You've holed the target! You've obliterated the target! click click 

代码

 import java.util.ArrayList; import java.util.List; public class PassAClass { public static void main(String[] args) { MagicGun gun = new MagicGun(); gun.loadWith(Pebble.class); gun.loadWith(Bullet.class); gun.loadWith(NuclearMissle.class); //gun.loadWith(Object.class); // Won't compile -- Object is not a Projectile for(int i=0; i<5; i++){ try { String effect = gun.shoot().effectOnTarget(); System.out.printf("You've %s the target!\n", effect); } catch (GunIsEmptyException e) { System.err.printf("click\n"); } } } } class MagicGun { /** * projectiles holds a list of classes that extend Projectile. Because of erasure, it * can't hold be a List<? extends Projectile> so we need the SuppressWarning. However * the only way to add to it is the "loadWith" method which makes it typesafe. */ private @SuppressWarnings("rawtypes") List<Class> projectiles = new ArrayList<Class>(); /** * Load the MagicGun with a new Projectile class. * @param projectileClass The class of the Projectile to create when it's time to shoot. */ public void loadWith(Class<? extends Projectile> projectileClass){ projectiles.add(projectileClass); } /** * Shoot the MagicGun with the next Projectile. Projectiles are shot First In First Out. * @return A newly created Projectile object. * @throws GunIsEmptyException */ public Projectile shoot() throws GunIsEmptyException{ if (projectiles.isEmpty()) throw new GunIsEmptyException(); Projectile projectile = null; // We know it must be a Projectile, so the SuppressWarnings is OK @SuppressWarnings("unchecked") Class<? extends Projectile> projectileClass = projectiles.get(0); projectiles.remove(0); try{ // http://www.java2s.com/Code/Java/Language-Basics/ObjectReflectioncreatenewinstance.htm projectile = projectileClass.newInstance(); } catch (InstantiationException e) { System.err.println(e); } catch (IllegalAccessException e) { System.err.println(e); } return projectile; } } abstract class Projectile { public abstract String effectOnTarget(); } class Pebble extends Projectile { @Override public String effectOnTarget() { return "annoyed"; } } class Bullet extends Projectile { @Override public String effectOnTarget() { return "holed"; } } class NuclearMissle extends Projectile { @Override public String effectOnTarget() { return "obliterated"; } } class GunIsEmptyException extends Exception { private static final long serialVersionUID = 4574971294051632635L; } 

你应该通过一个Class

 private void foo(Class<?> t){ if(t == String.class){ ... } else if(t == int.class){ ... } } private void bar() { foo(String.class); } 

哦,但这是丑陋的,非面向对象的代码。 当你看到“if / else”和“typeof”时,你应该考虑多态。 这是错误的路要走。 我认为仿制药在这里是你的朋友。

你打算处理多less种types?

更新:

如果你只是在谈论string和整数,这是你可能做的一个方法。 从接口XmlGenerator开始(足够用“foo”):

 package generics; public interface XmlGenerator<T> { String getXml(T value); } 

和具体的实现XmlGeneratorImpl:

  package generics; public class XmlGeneratorImpl<T> implements XmlGenerator<T> { private Class<T> valueType; private static final int DEFAULT_CAPACITY = 1024; public static void main(String [] args) { Integer x = 42; String y = "foobar"; XmlGenerator<Integer> intXmlGenerator = new XmlGeneratorImpl<Integer>(Integer.class); XmlGenerator<String> stringXmlGenerator = new XmlGeneratorImpl<String>(String.class); System.out.println("integer: " + intXmlGenerator.getXml(x)); System.out.println("string : " + stringXmlGenerator.getXml(y)); } public XmlGeneratorImpl(Class<T> clazz) { this.valueType = clazz; } public String getXml(T value) { StringBuilder builder = new StringBuilder(DEFAULT_CAPACITY); appendTag(builder); builder.append(value); appendTag(builder, false); return builder.toString(); } private void appendTag(StringBuilder builder) { this.appendTag(builder, false); } private void appendTag(StringBuilder builder, boolean isClosing) { String valueTypeName = valueType.getName(); builder.append("<").append(valueTypeName); if (isClosing) { builder.append("/"); } builder.append(">"); } } 

如果我运行这个,我得到以下结果:

 integer: <java.lang.Integer>42<java.lang.Integer> string : <java.lang.String>foobar<java.lang.String> 

我不知道这是你的想法。

如果你想通过types,比在Java中的等效

 java.lang.Class 

如果你想使用弱types的方法,那么你会简单地使用

 java.lang.Object 

和相应的操作员

 instanceof 

例如

 private void foo(Object o) { if(o instanceof String) { } }//foo 

然而,在Java中有原始types,它们不是类(即你的例子中的int),所以你需要小心。

真正的问题是你实际想要在这里实现的,否则很难回答:

或者,还有更好的方法?

你可以传递一个代表types的java.lang.Class的实例,即

 private void foo(Class cls)