如何在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)