gpt4 book ai didi

java - Java 的序列化文件与 C 语言(JNI)中的 `sizeof` 运算符不相等

转载 作者:行者123 更新时间:2023-11-30 18:40:52 27 4
gpt4 key购买 nike

我有一个 Java 代码,可以在 Java native 接口(interface)的帮助下检查对象的大小(以字节为单位)。我将要确定其大小的对象作为参数传递。
这是我的 Java 代码。

狗.java

import java.io.Serializable;



public class Dog implements Serializable {

public static final int LEGS = 4;



private double weight;
private String breed;



public void setWeight(double weight) {

this.weight = weight;
}



public void setBreed(String breed) {

this.breed = breed;
}



public double getWeight() {

return weight;
}



public String getBreed() {

return breed;
}
}

DogTester.java

import java.io.IOException;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;



public class DogTester {

public native double getDogSize(Object dog);



static {

System.loadLibrary("DogTester");
}



public static void main(String[] args) {

Dog dog = new Dog();



dog.setWeight(80.98);
dog.setBreed("Doberman");



DogTester tester = new DogTester();
System.out.println("Dog object required "+tester.getDogSize(dog)+" bytes");



try (FileOutputStream file = new FileOutputStream("Dog.ser");
ObjectOutputStream object = new ObjectOutputStream(file)) {

object.writeObject(dog);
} catch(IOException ioexception) {

System.out.println("IOException occured");
ioexception.printStackTrace();
}
}
}

我自己编写了这个头文件,而不是使用javah

DogTester.h

#include <jni.h>


#ifndef _Included_DogTester
#define _Included_DogTester

#ifdef __cplusplus
extern "C"
{
#endif



JNIEXPORT jdouble JNICALL Java_DogTester_getDogSize(jobject);



#ifdef __cplusplus
}
#endif

#endif

DogTester.c

#include <jni.h>
#include <stdio.h>
#include "DogTester.h"



JNIEXPORT jdouble JNICALL Java_DogTester_getDogSize(jobject obj) {

printf("Size of object from C program = %zu bytes", sizeof obj);
return sizeof obj;
}

我在我的Macbook pro 64位机器上编译了上面的C程序:

gcc -dynamiclib -I/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/include/darwin DogTester.c -o libDogTester.dylib  

它生成了一个名为libDogTester.dylib的文件。

我将 Java 程序编译为:

javac DogTester.java  

它生成了 DogTester.classDog.class 两者。

运行代码为:

java -Djava.library.path=. DogTester  

输出如下:

Adityas-MacBook-Pro:Java aditya$ java -Djava.library.path=. DogTester
Dog object required 8.0 bytes
Size of object from C program = 8 bytes

这清楚地意味着我的 dog 对象的大小是 8 个字节..
但是,右键单击由于序列化 dog 对象而生成的 Dog.ser 文件,并通过右键单击检查属性,它显示该文件占用 81 字节

而我的JavaC程序都说它只占用8字节

现在我有三个问题..

1>

即使 .ser 文件仅包含序列化对象,序列化后的对象是否会占用更多空间?

2>

如果第一个问题的答案是否定的,那么为什么我在右键单击 .ser 时看到输出和 get info 部分给出的大小存在差异文件?

3>

为什么会这样,即使在class DogTester中的println()方法之前调用了getDogSize()方法,结果还是在 C 程序 printf() 程序之前由 Java 程序打印?

注意:

当我在 C 的 printf("Size of object from C program = %zu bytes", sizeof obj) 过程中添加 \n 程序,如下所示:

printf("Size of object from C program = %zu bytes\n", sizeof obj);  

打印结果的顺序相反,新的输出是:

Adityas-MacBook-Pro:Java aditya$ java -Djava.library.path=. DogTester
Size of object from C program = 8 bytes
Dog object required 8.0 bytes

有什么帮助吗?提前致谢...

最佳答案

jobjectvoid *typedef(同义词);它是指向对象的指针,而不是对象本身。 sizeof obj 为您提供指针的大小,而不是所指向的对象的大小。

编辑

Why is it so, that even though getDogSize() method was called before println() method in class DogTester, the result was printed by Java program before the C programs printf() procedure?

C 中的标准输出通常是行缓冲的;在缓冲区已满或看到换行符之前,输出不会写入控制台。这就是为什么当您将 \n 添加到 C 输出时会看到行为变化的原因。

我不会假装理解 Java 如何相对于 C 缓冲输出,尤其是当涉及 JNI 时,但从行为中可以清楚地看出 Java 输出在 C 输出之前被刷新。

编辑2

Online C 2011 standard :

7.21.3 Files
...
3 ...When a stream is line buffered, characters are intended to betransmitted to or from the host environment as a block when a new-line character isencountered. Furthermore, characters are intended to be transmitted as a block to the hostenvironment when a buffer is filled, when input is requested on an unbuffered stream, orwhen input is requested on a line buffered stream that requires the transmission ofcharacters from the host environment...

7 At program startup, three text streams are predefined and need not be opened explicitly— standard input (for reading conventional input), standard output (for writingconventional output), and standard error (for writing diagnostic output). As initiallyopened, the standard error stream is not fully buffered; the standard input and standardoutput streams are fully buffered if and only if the stream can be determined not to referto an interactive device.

添加了强调。

关于java - Java 的序列化文件与 C 语言(JNI)中的 `sizeof` 运算符不相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24538260/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com