[英]Java- code in main method or not? If not, how do I call new method from main?
我有以下 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 */
當我運行該類時,它目前完全按照我的預期工作 - 並且只要我讓它運行,我就會不斷地將消息打印到控制台,顯示有關通過網絡發送的 PDU 的信息。
但是,我現在想從另一個類(我的 Gui 類)訪問有關通過網絡發送的消息(此類正在讀取並顯示在控制台中)的信息,以便我可以將這些信息呈現給用戶。
據我了解,為了讓另一個類能夠訪問該類收集的信息,我需要在主方法之外定義一個方法,並將所有這些代碼放入該方法中——因為其他類無法訪問另一個類類的主要方法? 這樣對嗎? 然后從我的主方法內部調用新方法?
我已經通過從我的主要方法中獲取所有代碼(如上所述)並將其放入以下方法中來完成此操作: public void receivePdu(){...}
然后,我嘗試使用receivePdu();
行從我的主方法調用receivePdu()
方法receivePdu();
,但我收到一條錯誤消息,提示“無法從類型 EspduReceiver 對非靜態方法 receivePdu() 進行靜態引用”,並建議我將“receivePdu()”的修飾符更改為“static””。
如果我繼續進行它建議的更改 - 這會破壞我的receivePdu()
方法中的代碼,該方法現在是一個public static void
方法,並且我會收到大量錯誤,例如“無法對非靜態引用進行靜態引用”靜態字段套接字、地址、數據包、pduFactory”。
有誰知道為什么我的receivePdu();
出現錯誤receivePdu();
在我的 main 方法中調用,我應該怎么做?
謝謝!
編輯 16/04/2014 @ 11:35
正如最初提到的,我已將所有代碼從 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 */
我遇到的問題是我收到錯誤“無法從類型 EspduReceiver 對非靜態方法 receivePdu() 進行靜態引用”,但是,如果我按照 Eclipse 的建議進行操作,並更改 'receivePdu() 的修飾符); 到“靜態”,我收到了很多其他錯誤,因為沒有其他內容是靜態的。
我不希望任何東西都是靜態的,因為我需要從程序中的其他類中引用此類中的方法。 有什么建議我可以做些什么來解決這個問題?
我相信您會收到錯誤消息,因為您將套接字、數據包、地址和 pduFactory 聲明了兩次——一次在 main 中,一次作為類的成員。 你真的需要決定你是否希望 receivePdu() 是靜態的。
您需要做出幾個決定:1) socket、packet、address 和 pduFactory 應該是 receivePdu() 本地的還是 EspduReceiver 的成員? 如果對此的答案是“local to receivePdu()”,那么您需要刪除這些變量的外部聲明。 如果答案是“EspduReceiver 的成員”,那么您需要刪除內部聲明,並且可能使用“this.socket”來引用每個聲明以明確引用。
2)與該決定交織在一起的是,這些變量是否應該是方法的局部變量,或者類的成員是否應該是靜態的。
所以我認為有三種總體方法:
A) receivePdu() 是一個靜態成員,它只訪問靜態和局部變量(將實例變量轉換為靜態變量(如@barak 所說)並刪除局部變量。)
B) receivePdu() 是在 EspduReceiver 的實例上調用的方法,因此您需要實例化 EspduReceiver 的實例才能調用它。 “socket”和其他變量應該是成員,而不是在receivePdu()中重新聲明
C) 將 receivePdu() 設置為單例類,並與“B”類似地進行。
祝你好運!
您的一個類中有一個主要方法,它是程序的起點。 將 gui、數據和邏輯分開是一個很好的做法。
所以在你的情況下,我會做以下設計。
class Main - 包含啟動 GUI 或 CMD 模式的主要方法
class EspduReceiverGUI - 用於輸入/輸出的 GUI 類
類EspduReceiver - 實現接口 EspduData
接口EspduData - 定義了getPDUData()方法
class PDU - 數據類對象
然后它看起來像這樣:
//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;
}
}
您也可以采用另一種方式,即 Receiver 類具有對 GUI 的引用,並會在新數據到達時通知它。 查看觀察者模式
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.