zoukankan      html  css  js  c++  java
  • Junit单测代码中java序列化失败的解决

    本文主要介绍在Junit单元测试中序列化时出现的java.io.NotSerializableException如何解决。

    关于序列化可以参见http://trinea.iteye.com/blog/1020511

    以下是Junit单测中的一段代码,主要功能是序列化一个接口变量

    interface GetDataInterface extends Serializable {
    
    	public Object getData();
    }
    
    public void testSerializable() {
    
    	GetDataInterface getData = new GetDataInterface() {
    
    		private static final long serialVersionUID = 1L;
    
    		@Override
    		public Object getData() {
    			return null;
    		}
    	};
    
    	ObjectOutputStream out;
    	try {
    		out = new ObjectOutputStream(new FileOutputStream("getData.obj"));
    		out.writeObject(getData);
    		out.close();
    		assertTrue(true);
    	} catch (FileNotFoundException e) {
    		e.printStackTrace();
    		assertFalse(true);
    	} catch (IOException e) {
    		e.printStackTrace();
    		assertFalse(true);
    	}
    }

    Junit运行testSerializable函数会抛出IOException异常,如下

    java.io.NotSerializableException: com.*.*.*.*.Test
    	at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    	at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    	at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    	at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    	at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    	at java.io.ObjectOutputStream.writeObject(Unknown Source)
    	at com.*.*.*.*.Test.testSerializable(AutoGetDataCacheTest.java:235)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at junit.framework.TestCase.runTest(TestCase.java:154)
    	at junit.framework.TestCase.runBare(TestCase.java:127)
    	at junit.framework.TestResult$1.protect(TestResult.java:106)
    	at junit.framework.TestResult.runProtected(TestResult.java:124)
    	at junit.framework.TestResult.run(TestResult.java:109)
    	at junit.framework.TestCase.run(TestCase.java:118)
    	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

    即找不到序列化的对象,这种情况一般出现在序列化对象的类没有实现Serializable接口,而这里明显已经实现了,将这段函数放到main函数中执行发现正常,接着比较就能发现main函数是静态的,我们将上面的testSerializable改成静态函数

    public static void testSerializable() 

    运行就会发现结果正常。  

    我们再试试对于一个类来说会怎么样

        public class ClassImplSerialize implements Serializable {
    
            private static final long serialVersionUID = 88940079192401092L;
        }
    
        public void testSerializable() {
    
            ClassImplSerialize getData = new ClassImplSerialize();
    
            ObjectOutputStream out;
            try {
                out = new ObjectOutputStream(new FileOutputStream("getData.obj"));
                out.writeObject(getData);
                out.close();
                assertTrue(true);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                assertFalse(true);
            } catch (IOException e) {
                e.printStackTrace();
                assertFalse(true);
            }
    
        }

    运行依旧会抛出上面类似的异常,这里我们将类ClassImplSerialize改为静态类,testSerializable依旧不变

    public static class ClassImplSerialize implements Serializable

    发现问题也可以解决。  

    原因:

    经评论中的鼎爷指点,总结原因如下

    内部类有一个隐含的引用指向外部类,这样序列化他的时候,这个引用指向的对象必须也是可序列化的,否则就报错。(所以我们把Junit的测试用例类实现Serializable也可以解决上面的问题)

    静态内部类不包含这个引用,所以只要自己可以序列化即可。

    对于静态函数能够正常通过,是因为这个内部类被静态函数引用,所以自己也相当于是静态的效果,不存在对外部类的引用了。

    更多感兴趣的可以看看评论1楼到4楼



    已有 5 人发表留言,猛击->>这里<<-参与讨论


    ITeye推荐



  • 相关阅读:
    清空DB
    C#生成PDF
    C#程序打包发布
    用C#实现生成PDF文档的方法
    SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY的比较
    如何在DataGridView中实现下拉列表可变的联动
    TreeList控件实现数据过滤功能
    SQL函数大全
    远程链接调用sql脚本
    gb2312简繁转换js兼容各种浏览器
  • 原文地址:https://www.cnblogs.com/trinea/p/2550075.html
Copyright © 2011-2022 走看看