Java 为什么';返回对当前对象的引用时是否总是返回相同的引用?

Java 为什么';返回对当前对象的引用时是否总是返回相同的引用?,java,drag-and-drop,Java,Drag And Drop,我对Java比较陌生,我正在尝试创建一个名为VisualObject的类,它的实例可以在JPanels之间拖放 这是用于VisualObject的getTransferData函数,它实现了Transferable: public Object getTransferData(DataFlavor d) throws UnsupportedFlavorException, IOException { if (d != visualObjectDataFl

我对Java比较陌生,我正在尝试创建一个名为
VisualObject
的类,它的实例可以在
JPanel
s之间拖放

这是用于
VisualObject
getTransferData
函数,它实现了
Transferable

    public Object getTransferData(DataFlavor d)
        throws UnsupportedFlavorException, IOException {

        if (d != visualObjectDataFlavor) {
            throw  new UnsupportedFlavorException(d);
        }   
        return this;
   }
但是,在我的
JPanel
s的
TransferHandler
中,我运行这一行

System.out.println(t.getTransferData(VisualObject.visualObjectDataFlavor).equals(t.getTransferData(VisualObject.visualObjectDataFlavor)));
它总是返回
false
。如何实际返回指向正在传输的对象的一致指针?还是有更好的方式转移

第二次编辑:

我的原始代码仍在下面,但问题仍然出现在这段简化得多的代码中:

package trytwo;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;

public class SimplifiedVisualObject implements Transferable {

    public static void main(String[] args) {        
        SimplifiedVisualObject a, b;
        a = new SimplifiedVisualObject();
        b = new SimplifiedVisualObject();
        try {
            System.out.println(a.getTransferData(DataFlavor.imageFlavor).equals(b.getTransferData(DataFlavor.imageFlavor)));
        } catch (UnsupportedFlavorException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Object getTransferData(DataFlavor flavor)
            throws UnsupportedFlavorException, IOException {
        return this;
    }

    @Override
    public DataFlavor[] getTransferDataFlavors() {
        return null;
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        return false;
    }

}
编辑:

下面是我编写的三个类:
VisualObject
(可转移的
)、
ObjectFrame
(在其内容窗格中保存
VisualObject
)和
Main
,它只创建了两个
ObjectFrame

VisualObject

package tryone;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.geom.Ellipse2D;
import java.io.IOException;
import javax.swing.JComponent;

public class VisualObject extends JComponent implements Transferable {

    private static final long serialVersionUID = -7105793092357377791L;
    public static DataFlavor visualObjectDataFlavor = new DataFlavor(VisualObject.class, "Visual Object");

    public VisualObject() {
        setOpaque(true);
        setLayout(null);
    }


    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.black);
        g2d.fill(new Ellipse2D.Double(0, 0,getWidth(),getHeight()));
    }

    @Override
    public Transferable getTransferData(DataFlavor d)
            throws UnsupportedFlavorException, IOException {

        if (d != visualObjectDataFlavor) {
            throw  new UnsupportedFlavorException(d);
        }   
        return this;
    }


    @Override
    public DataFlavor[] getTransferDataFlavors() {
        DataFlavor d[] = {visualObjectDataFlavor};
        return d;
    }


    @Override
    public boolean isDataFlavorSupported(DataFlavor d) {
        if (d == visualObjectDataFlavor) {
            return false;
        }
        return false;
    }

    public VisualObject getThis() {
        return this;
    }
}
ObjectFrame

package tryone;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.TransferHandler;


public class ObjectFrame extends JFrame implements DragGestureListener {

    private static final long serialVersionUID = 4330669242071962048L;
    protected Cursor draggingCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
    private JPanel panel;



    public ObjectFrame() {
        setVisible(true);
        setSize(300, 400);
        setLayout(new BorderLayout());
        setTitle("Object Tray");

        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        panel = new JPanel();
        panel.setBackground(Color.white);
        panel.setLayout(null);
        add(panel, BorderLayout.CENTER);


        final DragSource ds = new DragSource();
        final DragGestureListener handle = this;

        panel.setTransferHandler(new ObjectTransferHandler());

        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                VisualObject v = null;


                v = new VisualObject();
                v.setSize(50, 50);
                v.setLocation(100, 100);
                ds.createDefaultDragGestureRecognizer(v,
                        DnDConstants.ACTION_COPY, handle);
                panel.add(v);

                panel.repaint();
            }
        });
    }

    @Override
    public void dragGestureRecognized(DragGestureEvent dge) {
        if (dge.getComponent() instanceof Transferable) {
            dge.startDrag(draggingCursor, (Transferable) dge.getComponent());
        }
    }

    private class ObjectTransferHandler extends TransferHandler {
        private static final long serialVersionUID = 5072686271469629699L;

        public ObjectTransferHandler() {
        }

        public boolean canImport(TransferSupport t) {
            if (t.isDataFlavorSupported(VisualObject.visualObjectDataFlavor))  {
                return true;
            }
            return false;        
        }

        public boolean importData(TransferSupport ts) {
            Transferable t = ts.getTransferable();
            try {
                System.out.println(t.getTransferData(VisualObject.visualObjectDataFlavor) == (t.getTransferData(VisualObject.visualObjectDataFlavor)));

                return true;
            } catch (UnsupportedFlavorException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }           
            return false;
        }
    }
}
Main

package tryone;

import javax.swing.JFrame;

public class Main {

    public static void main(String[] args) {
        JFrame f1 = new ObjectFrame();
        JFrame f2 = new ObjectFrame();
    }

}

关于SimplifiedVisualObject版本:
getTransferData()
方法返回
this
。由于您正在创建两个不同的实例,因此您正在有效地比较
a.equals(b)
,通常情况下,除非覆盖
equals()
,否则该值始终为false

关于您的原始问题:如果调试代码,您将看到
VisualObject的情况也是如此。每次调用
getTransferData()
时,都会返回一个不同的实例,因此
equals()
比较返回false

如果您使用
DataFlavor.imageFlavor
它将按预期工作,尽管我无法确切解释原因

也许当使用未知风格时,默认的拖放实现不知道如何处理它。因此,可转移对象在传输过程中被序列化和反序列化,从而始终创建不同的实例


Edit:事实上,答案是,当您知道只在本地(在同一应用程序内)传输对象时,您应该创建新的
DataFlavor
visualObjectDataFlavor=newdataflavor(DataFlavor.javaJVMLocalObjectMimeType+“class=tryone.VisualObject”)(如示例中所示,要将其作为静态字段,请使用静态初始值设定项块)。这将让系统知道您正在应用程序中传输一个本地对象,因此它将返回通过对象比较测试的同一实例。

关于SimplifiedVisualObject版本:
getTransferData()
方法返回
This
。由于您正在创建两个不同的实例,因此您正在有效地比较
a.equals(b)
,通常情况下,除非覆盖
equals()
,否则该值始终为false

关于您的原始问题:如果调试代码,您将看到
VisualObject的情况也是如此。每次调用
getTransferData()
时,都会返回一个不同的实例,因此
equals()
比较返回false

如果您使用
DataFlavor.imageFlavor
它将按预期工作,尽管我无法确切解释原因

也许当使用未知风格时,默认的拖放实现不知道如何处理它。因此,可转移对象在传输过程中被序列化和反序列化,从而始终创建不同的实例


Edit:事实上,答案是,当您知道只在本地(在同一应用程序内)传输对象时,您应该创建新的
DataFlavor
visualObjectDataFlavor=newdataflavor(DataFlavor.javaJVMLocalObjectMimeType+“class=tryone.VisualObject”)(如示例中所示,要将其作为静态字段,请使用静态初始值设定项块)。这将让系统知道您正在应用程序中传输本地对象,因此它将返回通过对象比较测试的相同实例。

您是否在
VisaualObject
中实现了
equals
hashcode
方法?为什么要从该方法返回
对象
,而不是
可转移
?如果你实现了equals,那么它总是会返回false,作为一个有趣的测试,看看If==也会返回false(=(某种程度上)查看内存地址并测试它们是否是同一个对象)@RohitJain,我没有实现这些方法。我的理解是left notimplemented
equals
检查引用是否完全相同。也许我错了?不知道为什么会返回
对象
而不是
可转移
,该方法是由Eclipse自动生成的。我是否应该将其更改为可转移?@RichardTingle==也返回false。奇怪的是(至少在我的理解中是这样的)
this.equals(this)
VisualObject
中返回
true
。我甚至尝试过创建一个名为
getThis
的方法,该方法从字面上返回
this
,然后比较
getThis
的两个调用,发现它们是相等的!我不知道为什么
getThis
应该总是返回相同的值,但是
getTransferData
不会返回相同的值。我建议您编写一个最简单的代码示例来说明您的担忧。我发现很难相信,只有当你把每一行都写成你所拥有的时候,问题才会出现。例如,您真的需要任何与GUI相关的代码吗?e、 g.从一个名为A的类和另一个名为B的类开始,根据需要使用一个或两个方法。您是否在中实现了
equals
hashcode
方法