1

从我的搜索来看,我认为是对我的问题的一个很好的总结。也许,我错误地序列化或反序列化对象?或者如果序列化是正确的,我的问题是否有修复/解决方法?

我一直用这个作为Win32MediaSize类的参考。Win32MediaSize关于引用的类,我还有另一个稍微相关的问题。请参阅从 1640 开始的代码,它是静态初始化程序。我试图重现它,以便我可以看到执行顺序:

public clsss Why {

  static {
    String a = "Hello";
  }

  public class Not {
    static { // gives me a Cannot define static initializer in inner type error
      String b = "World";
    }
  }
}

这不是主要问题,但如果有人能在这里阐明一下,那就太好了。我个人认为这是问题所在,Win32MediaSize但我不知道为什么。我还尝试了他们在第 85 行和双括号上所做的事情,但都不起作用。删除关键字static确实可以解决错误,但我认为根据我的理解会产生不同的行为。

基本问题是我需要getSupportedAttributeValues为每个 PrintService 执行才能读取序列化数据,这违背了序列化数据的目的。序列化数据的原因是getSupportedAttributeValues完成时间太长(40 多秒)。

这是一个例外(valuerange取决于PrintService已加载的距离 - 在实际程序中,它正在另一个线程中加载;请参阅this以供参考):

java.io.InvalidObjectException: Integer value = 124 not in valid range 0..3for class class sun.print.Win32MediaSize
    at javax.print.attribute.EnumSyntax.readResolve(EnumSyntax.java:184)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeReadResolve(ObjectStreamClass.java:1056)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1761)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at java.util.HashMap.readObject(HashMap.java:1030)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at com.iii.print.PrintServiceLoader.readCachedData(PrintServiceLoader.java:355)
    at com.iii.print.PrintServiceLoader.main(PrintServiceLoader.java:420)

这是相关的代码位:

方法works()fails()这就是我遇到的问题。

void works() {
  HashMap<String, Object> m = null;
  HashMap<String, Object> mpa = null;
  doLookup(); // this is what causes the following call to not fail
  m = readCachedData( "a" );
  mpa = readCachedData( "b" );
}

void fails() {
  /* Assuming the files have already been created */
  HashMap<String, Object> m = null;
  HashMap<String, Object> mpa = null;
  m = readCachedData( "a" ); // this fails (see exception)
  mpa = readCachedData( "b" ); // this will work just fine
}


void doLookup() {
  PrintService[] psList = PrintServiceLookup.lookupPrintServices( DocFlavor.SERVICE_FORMATTED.PRINTABLE, null );

  HashMap<String, Object> cachedMedia = new HashMap<String, Object>();
  HashMap<String, Object> cachedMediaPrintableArea = new HashMap<String, Object>();
  for ( PrintService ps : psList ) {
    Object media = ps.getSupportedAttributeValues( Media.class, null, null );
    Object mediaPrintableArea = ps.getSupportedAttributeValues( MediaPrintableArea.class, null, null );
    cachedMedia.put( ps.getName(), media );
    cachedMediaPrintableArea.put( ps.getName(), mediaPrintableArea );
  }

  writeCachedData( "a", cachedMedia );
  writeCachedData( "b", cachedMediaPrintableArea );
}

boolean writeCachedData( String filename, Map<String, Object> data ) {
  boolean successful = true;

  if ( filename != null && !filename.isEmpty() && data != null && !data.isEmpty() ) {
    FileOutputStream fileOutStream = null;
    ObjectOutputStream objOutStream = null;

    try {
      fileOutStream = new FileOutputStream( filename );
      objOutStream = new ObjectOutputStream( fileOutStream );
      objOutStream.writeObject( data );
    } catch ( FileNotFoundException e ) {
      e.printStackTrace();
      successful = false;
    } catch ( IOException e ) {
      e.printStackTrace();
      successful = false;
    } finally {
      try {
        if ( objOutStream != null ) {
          objOutStream.close();
        }
      } catch ( IOException e ) {
        e.printStackTrace();
        successful = false;
      }
      try {
        if ( fileOutStream != null ) {
          fileOutStream.close();
        }
      } catch ( IOException e ) {
        e.printStackTrace();
        successful = false;
      }
    }

  } else {
    successful = false;
  }

  return successful;
}

Map<String, Object> readCachedData( String filename ) {
  Map<String, Object> cachedData = null;

  if ( filename != null && !filename.isEmpty() ) {
    File f = new File( ".", filename );
    if ( f.exists() ) {
      FileInputStream fileInStream = null;
      ObjectInputStream objInStream = null;

      try {
        fileInStream = new FileInputStream( f );
        objInStream = new ObjectInputStream( fileInStream );
        cachedData = (Map<String, Object>) objInStream.readObject();
      } catch ( FileNotFoundException e ) {
        e.printStackTrace();
      } catch ( IOException e ) {
        e.printStackTrace();
      } catch ( ClassNotFoundException e ) {
        e.printStackTrace();
      } finally {
        try {
          if ( fileInStream != null ) {
            fileInStream.close();
          }
        } catch ( IOException e ) {
          e.printStackTrace();
        }
        try {
          if ( objInStream != null ) {
            objInStream.close();
          }
        } catch ( IOException e ) {
          e.printStackTrace();
        }
      }
    }
  }

  return cachedData;
}

如您所知,我在 Windows 7 x64 上并使用 jdk 1.6.0_31。如果我遗漏了相关信息,请告诉我。

4

1 回答 1

1

关于你的第一个问题:

类 Not 应该是 public static,而不是 public。

public class Test {

    static {

    }

    public static class Not {
        static { 
            String b = "World";
        }
    }
}
于 2013-05-24T00:51:56.483 回答