简体   繁体   English

主要方法中的Java代码与否? 如果没有,我如何从 main 调用新方法?

[英]Java- code in main method or not? If not, how do I call new method from main?

I have the following Java class:我有以下 Java 类:

package openDIS;

import java.net.*;
import java.applet.*;
import java.awt.*;

import edu.nps.moves.disutil.*;
import edu.nps.moves.dis.*;

/*Receives PDUs from the network in IEEE format. */

public class EspduReceiver {

/*Max size of a PDU in binary format that can be received. Outdated- PDUs can be larger- but this is a reasonable starting point */
public static final int MAX_PDU_SIZE = 8192;

/*Retrieve PDU data for use by class methods */
MulticastSocket socket;
DatagramPacket packet;
InetAddress address;
PduFactory pduFactory = new PduFactory();


public static void main(String args[]){

    MulticastSocket socket;
    DatagramPacket packet;
    InetAddress address;
    PduFactory pduFactory = new PduFactory();

    try{
        /*Specify the socket to receive the data */
        socket = new MulticastSocket(EspduSender.PORT);
        address = InetAddress.getByName(EspduSender.DEFAULT_MULTICAST_GROUP);
        socket.joinGroup(address); 

        /*Loop infinitely, receiving datagrams */
        while(true){
            byte buffer[] = new byte[MAX_PDU_SIZE];
            packet = new DatagramPacket(buffer, buffer.length);

            socket.receive(packet);

            Pdu pdu = pduFactory.createPdu(packet.getData()); /*    Commented on 15/04/2014 @ 09:15 */

            if(pdu != null){
                System.out.print("Got PDU of type: " + pdu.getClass().getName());
                if(pdu instanceof EntityStatePdu){
                    EntityID eid = ((EntityStatePdu)pdu).getEntityID();
                    Vector3Double position = ((EntityStatePdu)pdu).getEntityLocation();
                    System.out.print(" EID:[" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "] ");
                    System.out.print(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]");
                } else if(!(pdu instanceof EntityStatePdu)){
                    System.out.println("There are no PDUs currently being received.");
                }
                System.out.println();
            }
        } /*end while */
    } /*end try */
    catch(Exception e){
        System.out.println(e);
        e.printStackTrace();
        System.out.println("This is where the error is being generated");
        /*09/04/2014 @ 17:100
         * If this exception gets called, presumably it either means that pdu is not an instance of EntityStatePdu, or
         * that pdu does not actually hold a packet.  */
    }
} /*end main */

/*Create an 'Inner Class' (use as a C struct) to hold all of the variables pertaining to each PDU- each instance of the class
 * will hold a separate PDU. 
 * Create a method in Gui.java that will retrieve each instance of the inner class, and display the values on screen.*/

public class PDU{

    public String entityID;
    public double xLocation;
    public double yLocation;
    public double zLocation;
}



} /*end class */

When I run the class, it is currently working exactly as I'd intended- and I continually get messages printed to the console displaying information about the PDUs being sent across the network, for as long as I leave it running.当我运行该类时,它目前完全按照我的预期工作 - 并且只要我让它运行,我就会不断地将消息打印到控制台,显示有关通过网络发送的 PDU 的信息。

However, I now want to access the information about the messages being sent over the network that this class is reading and displaying in the console, from another class- my Gui class, so that I can present this information to the user.但是,我现在想从另一个类(我的 Gui 类)访问有关通过网络发送的消息(此类正在读取并显示在控制台中)的信息,以便我可以将这些信息呈现给用户。

As I understand, in order for another class to be able to access the information collected by this class, I will need to define a method outside of my main method, and put all of this code into that method- as other classes cannot access another class' main method?据我了解,为了让另一个类能够访问该类收集的信息,我需要在主方法之外定义一个方法,并将所有这些代码放入该方法中——因为其他类无法访问另一个类类的主要方法? Is this correct?这样对吗? Then call the new method from inside my main method?然后从我的主方法内部调用新方法?

I have done this by taking all of the code from inside my main method (as it is above) and putting it inside the following method instead: public void receivePdu(){...}我已经通过从我的主要方法中获取所有代码(如上所述)并将其放入以下方法中来完成此操作: public void receivePdu(){...}

I am then trying to call the receivePdu() method from my main method using the line receivePdu();然后,我尝试使用receivePdu();行从我的主方法调用receivePdu()方法receivePdu(); , but I get an error that says "Cannot make a static reference to the non- static method receivePdu() from the type EspduReceiver", and suggests that I change modifier of 'receivePdu()' to 'static'". ,但我收到一条错误消息,提示“无法从类型 EspduReceiver 对非静态方法 receivePdu() 进行静态引用”,并建议我将“receivePdu()”的修饰符更改为“static””。

If I go ahead and make the change it recommends- that breaks the code in my receivePdu() method, which is now a public static void method, and I get a load of errors such as "Cannot make a static reference to the non-static field socket, address, packet, pduFactory".如果我继续进行它建议的更改 - 这会破坏我的receivePdu()方法中的代码,该方法现在是一个public static void方法,并且我会收到大量错误,例如“无法对非静态引用进行静态引用”静态字段套接字、地址、数据包、pduFactory”。

Does anyone know why I'm getting the error on my receivePdu();有谁知道为什么我的receivePdu();出现错误receivePdu(); call inside my main method, and how I should be doing it instead?在我的 main 方法中调用,我应该怎么做?

Thanks!谢谢!

Edit 16/04/2014 @ 11:35编辑 16/04/2014 @ 11:35

As mentioned originally, I have moved all of the code from the main method to another method called receivePdu() , and am now just calling that method from the main instead- I've added the updated code below:正如最初提到的,我已将所有代码从 main 方法移动到另一个名为receivePdu()方法,现在我只是从 main 调用该方法 - 我在下面添加了更新的代码:

package openDIS;

import java.net.*;
import java.applet.*;
import java.awt.*;

import edu.nps.moves.disutil.*;
import edu.nps.moves.dis.*;

/*Receives PDUs from the network in IEEE format. */

public class EspduReceiver {

/*Max size of a PDU in binary format that can be received. Outdated- PDUs can be larger- but this is a reasonable starting point */
public static final int MAX_PDU_SIZE = 8192;

/*Retrieve PDU data for use by class methods */
MulticastSocket socket;
DatagramPacket packet;
InetAddress address;
PduFactory pduFactory = new PduFactory();

public void receivePdu(){

    try{
        /*Specify the socket to receive the data */
        socket = new MulticastSocket(EspduSender.PORT);
        address = InetAddress.getByName(EspduSender.DEFAULT_MULTICAST_GROUP);
        socket.joinGroup(address); 

        /*Loop infinitely, receiving datagrams */
        while(true){
            byte buffer[] = new byte[MAX_PDU_SIZE];
            packet = new DatagramPacket(buffer, buffer.length);

            socket.receive(packet);

            Pdu pdu = pduFactory.createPdu(packet.getData()); /*    Commented on 15/04/2014 @ 09:15 */

            if(pdu != null){
                System.out.print("Got PDU of type: " + pdu.getClass().getName());
                if(pdu instanceof EntityStatePdu){
                    EntityID eid = ((EntityStatePdu)pdu).getEntityID();
                    Vector3Double position = ((EntityStatePdu)pdu).getEntityLocation();
                    System.out.print(" EID:[" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "] ");
                    System.out.print(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]");
                } else if(!(pdu instanceof EntityStatePdu)){
                    System.out.println("There are no PDUs currently being received.");
                }
                System.out.println();
            }
        } /*end while */
    } /*end try */
    catch(Exception e){
        System.out.println(e);
        e.printStackTrace();
        System.out.println("This is where the error is being generated");
        /*09/04/2014 @ 17:100
         * If this exception gets called, presumably it either means that pdu is not an instance of EntityStatePdu, or
         * that pdu does not actually hold a packet.  */
    }
}

public static void main(String args[]){

    receivePdu();

} /*end main */

/*Create an 'Inner Class' (use as a C struct) to hold all of the variables pertaining to each PDU- each instance of the class
 * will hold a separate PDU. 
 * Create a method in Gui.java that will retrieve each instance of the inner class, and display the values on screen.*/

public class PDU{

    public String entityID;
    public double xLocation;
    public double yLocation;
    public double zLocation;
}



} /*end class */

The issue that I am having is that I get the error "Cannot make a static reference to the non-static method receivePdu() from the type EspduReceiver", however, if I do what Eclipse suggests, and change the modifier of 'receivePdu();我遇到的问题是我收到错误“无法从类型 EspduReceiver 对非静态方法 receivePdu() 进行静态引用”,但是,如果我按照 Eclipse 的建议进行操作,并更改 'receivePdu() 的修饰符); to 'static', I get a load of other errors because nothing else is static.到“静态”,我收到了很多其他错误,因为没有其他内容是静态的。

I do not want anything to be static, because I need to reference the methods in this class from other classes in my program.我不希望任何东西都是静态的,因为我需要从程序中的其他类中引用此类中的方法。 Any suggestions what I can do to resolve this?有什么建议我可以做些什么来解决这个问题?

I believe you are getting an error because you have socket, packet, address and pduFactory declared twice -- once in main and once as members of the class.我相信您会收到错误消息,因为您将套接字、数据包、地址和 pduFactory 声明了两次——一次在 main 中,一次作为类的成员。 And you really need to decide if you want receivePdu() to be static or not.你真的需要决定你是否希望 receivePdu() 是静态的。

You have a couple decisions to make: 1) Should socket, packet, address and pduFactory be local to receivePdu() or members of EspduReceiver?您需要做出几个决定:1) socket、packet、address 和 pduFactory 应该是 receivePdu() 本地的还是 EspduReceiver 的成员? If the answer to this its "local to receivePdu()", then you need to remove the outer declaration for these variables.如果对此的答案是“local to receivePdu()”,那么您需要删除这些变量的外部声明。 If the answer is "members of EspduReceiver" then you need to remove the inner declaration, and maybe refer to each using "this.socket" to make the references clear.如果答案是“EspduReceiver 的成员”,那么您需要删除内部声明,并且可能使用“this.socket”来引用每个声明以明确引用。

2) Intertwined with that decision is if those variables should be local to the method or members of the class is if receivePdu() is static or not. 2)与该决定交织在一起的是,这些变量是否应该是方法的局部变量,或者类的成员是否应该是静态的。

So I think there are three overall approaches:所以我认为有三种总体方法:

A) receivePdu() is a static member which accesses only static and local variables (convert the instance variables to static variables (as @barak says) and remove the local variables.) A) receivePdu() 是一个静态成员,它只访问静态和局部变量(将实例变量转换为静态变量(如@barak 所说)并删除局部变量。)

B) receivePdu() is a method invoked on an instance of EspduReceiver, so you need to instantiate an instance of EspduReceiver in order to envoke it. B) receivePdu() 是在 EspduReceiver 的实例上调用的方法,因此您需要实例化 EspduReceiver 的实例才能调用它。 "socket" and the other variables should be members, not re-declared in receivePdu() “socket”和其他变量应该是成员,而不是在receivePdu()中重新声明

C) set up receivePdu() as a singleton class, and proceed similarly to "B". C) 将 receivePdu() 设置为单例类,并与“B”类似地进行。

good luck!祝你好运!

There is one main methode in one of your classes which is the starting point of the program.您的一个类中有一个主要方法,它是程序的起点。 It is a good practise to seperate gui, data and logic.将 gui、数据和逻辑分开是一个很好的做法。

So in your case I would do the following design.所以在你的情况下,我会做以下设计。

class Main - contains your main methode which starts either GUI or CMD mode class Main - 包含启动 GUI 或 CMD 模式的主要方法

class EspduReceiverGUI - Your GUI class for input/output class EspduReceiverGUI - 用于输入/输出的 GUI 类

class EspduReceiver - which implements an interface EspduDataEspduReceiver - 实现接口 EspduData

interface EspduData - which defines a methode getPDUData()接口EspduData - 定义了getPDUData()方法

class PDU - Data class object class PDU - 数据类对象

Then it will look something like this:然后它看起来像这样:

//Startpoint
public class Main
{
    public static void main(String[] args)
    {
         new EspduReceiverGUI();    //start gui somehow
    }
}

//GUI
public class EspduReceiverGUI
{
    //only exists once
    private static EspduData handler;

    //Get your Data and do something with it
    public EspduReceiverGUI()
    {
         handler = new EspduReceiver();
         PDU data = handler.getPDUData();

         doSomething(data);
    }
}

//Receiver
public class EspduReceiver implements EspduData
{
    //Variablen, Sockets etc.

    public PDU getPDUData()
    {
        //receive data and return
        //return pdu;
    }

}

You could also do it the otherway around that the Receiver class has a reference to the GUI and will inform it when new data arrives.您也可以采用另一种方式,即 Receiver 类具有对 GUI 的引用,并会在新数据到达时通知它。 See the Observer Pattern查看观察者模式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM