首页 \ 问答 \ 使用访问者模式或反射的Java动态类转换?(Java dynamic class casting using visitor pattern or reflection? Missing steps or bad implementation?)

使用访问者模式或反射的Java动态类转换?(Java dynamic class casting using visitor pattern or reflection? Missing steps or bad implementation?)

我正在创建基于用户输入具有共同属性的对象,然后将对象传递给将根据对象类型采取适当操作的公共方法。 我已经能够使用访问者类来完成这项工作,但这并不是我想要的。 我希望能够在公共方法中确定对象类型,然后访问与该对象关联的方法。 我不确定我是否接近并且只是遗漏了一些东西,或者我只是执行不好......或两者都是=)。 这是我的(完整)代码:

package com.theory.bang.big;

public interface Particle
{
    public enum ParticleType {
        QUARK,
        LEPTON
}

int processParticle(Particle p);

}


package com.theory.bang.big;

import java.util.ArrayList;
public class Quark implements Particle
{
ArrayList<String> flavorList;

/**
 * Constructor for objects of class Quark
 */
public Quark() 
{
    flavorList = new ArrayList<String>();
    flavorList.add("up");
    flavorList.add("down");
    flavorList.add("charm");
    flavorList.add("strange");
    flavorList.add("top");
    flavorList.add("bottom");
}

public ArrayList<String> getFlavors()
{
    return flavorList;
}


@Override
public int processParticle(Particle p)
{
    System.out.println("In processParticle(Quark)");

    // Never called?

    return 0;
}

}



package com.theory.bang.big;

import java.util.ArrayList;

public class Lepton implements Particle
{
ArrayList<String> typeList;

/**
 * Constructor for objects of class Lepton
 */
public Lepton() 
{   
    typeList = new ArrayList<String>();
    typeList.add("electron");
    typeList.add("electron neutrino");
    typeList.add("muon");
    typeList.add("muon neutrino");
    typeList.add("tau");
    typeList.add("tau neutrino");
}

public ArrayList<String> getTypes()
{
    return typeList;
}

@Override
public int processParticle(Particle p)
{
    System.out.println("In processParticle(Lepton)");

    return 0;
}
}


package com.theory.bang.big;

import java.lang.reflect.*;

class ParticleVisitor
{
public void visit( Quark q )
{
    System.out.println("Quark:[" + q.getFlavors() + "]");
}

public void visit( Lepton l )
{
    System.out.println("Lepton:[" + l.getTypes() + "]");
}

public void visit( Object e ) throws Exception
{
    Method m = getClass().getMethod
     ( "visit", new Class[]{e.getClass()} );
    m.invoke( this, new Object[]{e} );
}
}


package com.theory.bang.big;

import java.io.File;

public class Accelerate implements Particle
{
/**
 * Constructor for objects of class Accelerate
 */
public Accelerate(Particle p)
{
    processParticle(p);
}

//@Override
public int processParticle(Particle p)
{
    try {

        ParticleVisitor pv = new ParticleVisitor();
        pv.visit(p);
    } catch (Exception x) {
        System.out.println(x);
    }

   return 0;
}
}


package com.theory.bang.big;

import java.io.File;
import java.util.Scanner;

public class Physics
{
public static void main(String[] args)
{
   boolean done = false;

   while (!done) {
       System.out.print("Enter the particle [Quark or Lepton]: ");
       Scanner in = new Scanner(System.in);      
       String input = in.next();

       if (input.equals("Quark")) {
           System.out.println("Quark");
           Quark q = new Quark();
           new Accelerate(q);
        } else if (input.equals("Lepton")) {
            System.out.println("Lepton");
            Lepton l = new Lepton();
            new Accelerate(l);
        } else {
            done = true;
        }
    }

}
}

目前我可以通过访问方法打印Quark风格和Lepton类型,但我需要的是能够为Accelerate中的各个对象执行(实现)getter / setter(例如getSpin(),setSpin(double s)) ()。 我错过了什么? 或者有更好的方法来实现这个?

非常感谢您的宝贵时间。

-Walter


I am creating objects that will have properties in common based on user input and then passing the objects to a common method that will take appropriate action based on the object type. I've been able to sort of get this working using a visitor class but it is not quite what I want. I want to be able to determine the object type in the common method and then access the methods associated with that object. I am not sure if I am close and just missing something or if I just have a bad implementation... or both =). Here is my (complete) code:

package com.theory.bang.big;

public interface Particle
{
    public enum ParticleType {
        QUARK,
        LEPTON
}

int processParticle(Particle p);

}


package com.theory.bang.big;

import java.util.ArrayList;
public class Quark implements Particle
{
ArrayList<String> flavorList;

/**
 * Constructor for objects of class Quark
 */
public Quark() 
{
    flavorList = new ArrayList<String>();
    flavorList.add("up");
    flavorList.add("down");
    flavorList.add("charm");
    flavorList.add("strange");
    flavorList.add("top");
    flavorList.add("bottom");
}

public ArrayList<String> getFlavors()
{
    return flavorList;
}


@Override
public int processParticle(Particle p)
{
    System.out.println("In processParticle(Quark)");

    // Never called?

    return 0;
}

}



package com.theory.bang.big;

import java.util.ArrayList;

public class Lepton implements Particle
{
ArrayList<String> typeList;

/**
 * Constructor for objects of class Lepton
 */
public Lepton() 
{   
    typeList = new ArrayList<String>();
    typeList.add("electron");
    typeList.add("electron neutrino");
    typeList.add("muon");
    typeList.add("muon neutrino");
    typeList.add("tau");
    typeList.add("tau neutrino");
}

public ArrayList<String> getTypes()
{
    return typeList;
}

@Override
public int processParticle(Particle p)
{
    System.out.println("In processParticle(Lepton)");

    return 0;
}
}


package com.theory.bang.big;

import java.lang.reflect.*;

class ParticleVisitor
{
public void visit( Quark q )
{
    System.out.println("Quark:[" + q.getFlavors() + "]");
}

public void visit( Lepton l )
{
    System.out.println("Lepton:[" + l.getTypes() + "]");
}

public void visit( Object e ) throws Exception
{
    Method m = getClass().getMethod
     ( "visit", new Class[]{e.getClass()} );
    m.invoke( this, new Object[]{e} );
}
}


package com.theory.bang.big;

import java.io.File;

public class Accelerate implements Particle
{
/**
 * Constructor for objects of class Accelerate
 */
public Accelerate(Particle p)
{
    processParticle(p);
}

//@Override
public int processParticle(Particle p)
{
    try {

        ParticleVisitor pv = new ParticleVisitor();
        pv.visit(p);
    } catch (Exception x) {
        System.out.println(x);
    }

   return 0;
}
}


package com.theory.bang.big;

import java.io.File;
import java.util.Scanner;

public class Physics
{
public static void main(String[] args)
{
   boolean done = false;

   while (!done) {
       System.out.print("Enter the particle [Quark or Lepton]: ");
       Scanner in = new Scanner(System.in);      
       String input = in.next();

       if (input.equals("Quark")) {
           System.out.println("Quark");
           Quark q = new Quark();
           new Accelerate(q);
        } else if (input.equals("Lepton")) {
            System.out.println("Lepton");
            Lepton l = new Lepton();
            new Accelerate(l);
        } else {
            done = true;
        }
    }

}
}

Currently I can print the Quark flavors and Lepton types via the visit methods but what I need is to be able to execute (to be implemented) getter/setters (e.g. getSpin(), setSpin(double s)) for the respective objects in Accelerate(). What am I missing? Or is there a better way to implement this?

Thank you very much for your time.

-Walter


原文:https://stackoverflow.com/questions/18567202
更新时间:2023-09-26 07:09

最满意答案

这只是关于对象将被存储在哪里(堆栈或堆)或应用程序行为可能被破坏?

这是一个问题。 另一个值得关注的问题应该是关于值类型和引用类型之间的语义差异。 当你指定一个对象的值来分配一个这个对象的副本或者一个指向堆中对象的引用的副本时,你想要吗? 这可能是一个大问题 。 我为什么这么说? 无论你传递什么对象,如果你把它作为一个类,你将传递一个引用,并且至少在其中一个字段上进行的任何更改都会反映到您传递的对象,而不是传递给您的对象的副本。 这可能是一个问题或不是。 然而,为了给出一个具体的答案,你必须运行你的代码库并且彻底地查看你的对象是如何被使用的。 只有在做完这些之后,你才能够给出正确的答案。


Is this only about where the object will be stored (stack or heap) or application behavior may be broken?

This is one concern. One more significant concern should be about the difference in the semantics between a value type and a reference type. Do you want when you assign a value of your object to assign a copy of this object or a copy of the reference, which points to an object in the heap? This could be a big issue. Why I say so? Wherever you pass your object, if you make it a class, you will pass a reference and any change that will be made on at least one of it's fields would be reflected to the object you passed and not to a copy of the object you passed. This may be an issue or not. However, in order you give a concrete answer, you have to run though your code base and look there thoroughly how your object is used. Only after doing this, you be in a position to give the right answer.

相关问答

更多
  • 前言: 虽然我的答案仍然没问题,但我发现莱布的答案比我的好,因为: 它教我一个我不知道的诡计(litb的答案通常有这种效果,但这是我第一次写下来) 它完全回答了这个问题(即,将原始结构的部分初始化为零) 所以,请在我的面前考虑莱布的答案。 事实上,我建议这个问题的作者认为莱布的答案是正确的。 原始答案 因为真正的对象将在memset之前被初始化,然后被零覆盖,所以放入一个真正的对象(即std :: string)等将会中断。 使用初始化列表不适用于g ++(我很惊讶......)。 初始化它,而不是在CMy ...
  • 是的,这非常安全。 当您按值返回时,它将结构的成员复制到调用者的结构中。 只要结构不包含任何指向本地对象的指针,它就是有效的。 返回结构往往不常见,因为如果它们很大,则需要大量的复制。 但有时候我们会把数组放入结构中,以便像其他数据类型一样,通过值传递它们并返回值(数组通常衰减为用作参数或返回值的指针)。 原始提问者的附录 (我相信@Barmar不会介意......) 正如@DanielH指出的那样, 对于amd64的SysV ABI ,编译器会根据值返回结构。 如果它很小,整个结构可以返回寄存器(读取:快 ...
  • 这是一个class的例子。 请注意如何更改名称,更新两个变量所引用的实例。 Bob现在是Sue ,无处不在Bob被引用。 class SomeClass { var name: String init(name: String) { self.name = name } } var aClass = SomeClass(name: "Bob") var bClass = aClass // aClass and bClass now reference the sa ...
  • 对我来说,这似乎是一个坏主意。 IPC :: Semaphore 可以解决这个问题,如果你能让它们在一个信号处理程序中正常工作 - 如果在处理程序退出之前控制权不会返回,那么你运气不好。 但是,您可以通过锁定父级并让孩子在锁上等待,直到初始化完成; 处理程序不涉及信号量。 我想你实际上只需要一把锁。 无论如何: my @array = (1..10); my $x = 'x'; $SIG{'USR1'} = sub { print "SIGUSER1\n"; undef @array; ...
  • 我建议使用用户控件作为DataGridView的唯一列的控件。 然后用户控件可以在您喜欢的布置中包含名称,ID,年龄和组标签。 如何在DataGridViews中使用用户控件,请参阅: https : //docs.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-host-controls-in-windows-forms-datagridview-cells I would recommend to use a user cont ...
  • 这只是关于对象将被存储在哪里(堆栈或堆)或应用程序行为可能被破坏? 这是一个问题。 另一个值得关注的问题应该是关于值类型和引用类型之间的语义差异。 当你指定一个对象的值来分配一个这个对象的副本或者一个指向堆中对象的引用的副本时,你想要吗? 这可能是一个大问题 。 我为什么这么说? 无论你传递什么对象,如果你把它作为一个类,你将传递一个引用,并且至少在其中一个字段上进行的任何更改都会反映到您传递的对象,而不是传递给您的对象的副本。 这可能是一个问题或不是。 然而,为了给出一个具体的答案,你必须运行你的代码库并 ...
  • 不,这是不可能的。 但您可能想要使用条件编译 : #define UseFooPropertery // define pre-processor symbol class A { #if UseFooProperty // check if symbol is defined public Foo FooProperty{get; set} #endif } 您也可以使用Conditional属性代替#if/#endif预处理程序指令: #define UseFooPro ...
  • 如果你真的想要,那就继续前进吧: $ mv .git FolderA/ $ cd FolderA/ $ git add . 但请注意FolderB所有文件现在都不受源代码控制: $ git commit -m "Remove all but FolderA from source control" [master d044479] Remove all but FolderA from source control 10 files changed, 5 deletions(-) rename Fol ...
  • 要创建内部类,您需要从外部类的实例执行此操作或将内部类设置为static : 因此,在PhotoGalleryFragment创建实例: public class PhotoGalleryFragment { void createTask(String query) { new FetchItemsTask(query); //return it if you like, or just call execute here, doesn't matter } ...
  • 你需要说.o文件依赖于.c文件: main.o: main.c <---- HERE $(CC) -c main.c count.o: count.c <---- HERE $(CC) -c count.c bin2csv.o: bin2csv.c <---- HERE 否则, make没有理由认为它需要重新制作.o文件。 You need to say that the .o files depend on the .c files: main.o: main.c <---- ...

相关文章

更多

最新问答

更多
  • h2元素推动其他h2和div。(h2 element pushing other h2 and div down. two divs, two headers, and they're wrapped within a parent div)
  • 创建一个功能(Create a function)
  • 我投了份简历,是电脑编程方面的学徒,面试时说要培训三个月,前面
  • PDO语句不显示获取的结果(PDOstatement not displaying fetched results)
  • Qt冻结循环的原因?(Qt freezing cause of the loop?)
  • TableView重复youtube-api结果(TableView Repeating youtube-api result)
  • 如何使用自由职业者帐户登录我的php网站?(How can I login into my php website using freelancer account? [closed])
  • SQL Server 2014版本支持的最大数据库数(Maximum number of databases supported by SQL Server 2014 editions)
  • 我如何获得DynamicJasper 3.1.2(或更高版本)的Maven仓库?(How do I get the maven repository for DynamicJasper 3.1.2 (or higher)?)
  • 以编程方式创建UITableView(Creating a UITableView Programmatically)
  • 如何打破按钮上的生命周期循环(How to break do-while loop on button)
  • C#使用EF访问MVC上的部分类的自定义属性(C# access custom attributes of a partial class on MVC with EF)
  • 如何获得facebook app的publish_stream权限?(How to get publish_stream permissions for facebook app?)
  • 如何防止调用冗余函数的postgres视图(how to prevent postgres views calling redundant functions)
  • Sql Server在欧洲获取当前日期时间(Sql Server get current date time in Europe)
  • 设置kotlin扩展名(Setting a kotlin extension)
  • 如何并排放置两个元件?(How to position two elements side by side?)
  • 如何在vim中启用python3?(How to enable python3 in vim?)
  • 在MySQL和/或多列中使用多个表用于Rails应用程序(Using multiple tables in MySQL and/or multiple columns for a Rails application)
  • 如何隐藏谷歌地图上的登录按钮?(How to hide the Sign in button from Google maps?)
  • Mysql左连接旋转90°表(Mysql Left join rotate 90° table)
  • dedecms如何安装?
  • 在哪儿学计算机最好?
  • 学php哪个的书 最好,本人菜鸟
  • 触摸时不要突出显示表格视图行(Do not highlight table view row when touched)
  • 如何覆盖错误堆栈getter(How to override Error stack getter)
  • 带有ImageMagick和许多图像的GIF动画(GIF animation with ImageMagick and many images)
  • USSD INTERFACE - > java web应用程序通信(USSD INTERFACE -> java web app communication)
  • 电脑高中毕业学习去哪里培训
  • 正则表达式验证SMTP响应(Regex to validate SMTP Responses)