Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的序列化文件和C语言(JNI)中的'sizeof'运算符不相等_Java_C_Macos_Java Native Interface_Osx Mavericks - Fatal编程技术网

Java中的序列化文件和C语言(JNI)中的'sizeof'运算符不相等

Java中的序列化文件和C语言(JNI)中的'sizeof'运算符不相等,java,c,macos,java-native-interface,osx-mavericks,Java,C,Macos,Java Native Interface,Osx Mavericks,我有一个Java代码,它在Java本机接口的帮助下检查对象的大小(以字节为单位)。我将要确定其大小的对象作为参数传递。 这是我的Java代码 Dog.java import java.io.Serializable; public class Dog implements Serializable { public static final int LEGS = 4; private double weight; private String breed;

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

Dog.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

狗测试仪

#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
它生成了一个名为
libDogTester.dylib
的文件

我将
Java
程序编译为:

javac DogTester.java  
它同时产生了
DogTester.class
Dog.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字节

而我的
Java
C
程序都说它只占用
8个字节

现在我有三个问题

1> 即使
.ser
文件只包含
序列化对象,对象在序列化时是否会占用更多空间

2> 如果第一个问题的答案是否定的,那么为什么右键单击
.ser
文件时,我会看到输出和
获取信息部分给出的大小不同

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

注: 当我在
printf中添加
\n
时(“C程序中对象的大小=%zu字节”,obj的大小)
过程在我的
C
程序中,如下所示:

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
有什么帮助吗?
提前感谢…

对前两个问题的解答

1> 在序列化文件中,您保存的是
dog
对象本身。
但是在程序中,您试图打印的是
参考变量-dog
的大小,而不是
dog
对象的大小。
因此,两者之间存在差异

2>
可能没有。实际上没有区别。仔细阅读第一个答案。它说明了我们看到不同结果的原因

sizeof操作符告诉您指向dog对象的指针的大小。而不是对象本身的大小。物体本身肯定比这个大。我猜是这样的

  • 8字节对象开销
  • 每个整数4个字节
  • 每个方法8字节
  • 8字节为双字节
  • 字符串的x字节

你自己把它加起来,得到大小的近似值。

jobject
typedef
(同义词)表示
void*
;它是指向对象的指针,而不是对象本身
sizeof obj
提供指针的大小,而不是指向的对象的大小

编辑

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

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

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

Edit2

:

7.21.3文件

3…当一个流被行缓冲时,字符被指定为 当输入新行字符时,作为块传输到主机环境或从主机环境传输 遇到。此外,字符打算作为块传输到主机 当缓冲区已填充、在未缓冲流上请求输入时的环境,或 当在需要传输数据的线路缓冲流上请求输入时 主机环境中的字符…

7在程序启动时,预先定义了三个文本流,无需显式打开 -标准输入(用于读取常规输入),标准输出(用于写入 常规输出)和标准错误(用于写入诊断输出)。一如当初 打开时,标准错误流未完全缓冲;标准输入与标准 当且仅当可以确定流不引用时,输出流才被完全缓冲 连接到交互式设备。
增加了重点。

我认为你需要更多地浓缩和隔离你的问题。大多数人不会费力阅读5个来源的文件和你读过的小说wrote@BrandonYates我做不到。所有文件都相互依赖。请帮忙。我有三个小问题。你真的需要在你的帖子中用25行来向我展示“吠叫”和“咆哮”功能吗?@BrandonYates好的,我将删除它们对象序列化与
sizeof
完全不同,它们都没有告诉你对象使用了多少内存。对象序列化记录类名、字段名以及标头等内容
sizeof
告诉您
jobject
句柄的大小,无论实际对象是什么,句柄大小都是相同的。我合法地回答了我自己的前两点问题。我需要第三个问题的答案。它能经受住法庭的审查吗?我们怎么能这么肯定这是合法的?是的,我们可以回答我们自己的问题。我接受回答
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