java继承内存怎么分配

java没有地址,主函数就用类似c的方式写了
aa保存的地址应该和&(aa.i)一样吧,那bb保存的又是谁的地址呢,是&(bb.j)吗还是&(bb.i)


class A
{
    int i;
    public void f()
    {
        System.out.printf("AAAA\n");
    }
}
class B extends A
{
    int j;
    public void f()
    {
        System.out.printf("BBBB\n");
    }
}
class Usually_1
{
    public static void main(String[] args)
    {
        A aa=new A();
        B bb=new B();
        System.out.printf("%p\n",aa);
        System.out.printf("%p\n",&aa);
        System.out.printf("%p\n",&(aa.i));

        System.out.printf("%p\n",bb);
        System.out.printf("%p\n",&bb);
        System.out.printf("%p\n",&(bb.i));
        System.out.printf("%p\n",&(bb.j));
    }
}


不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这篇博客: java实现二叉搜索树-前中后层序遍历中的 不bb基础了,直接开干 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    使用递归本身就是借助了栈的思想。
    *前中后和层序遍历四种遍历算法的实现

    public class BinarySearchTree {
    
        BinarySearchTree[] queue = new BinarySearchTree[200];
        int front=0,rear=0;
        int data;
        BinarySearchTree left;
        BinarySearchTree right;
    
        /**
         * 二叉树的构造方法,构造方法不能有返回值,void也不行
         * @param data
         */
        public  BinarySearchTree(int data){
            this.data = data;
             left = null;
             right = null;
        }
    
        /**
         * 二叉树的插入方法
         * @param root
         * @param data
         */
        public static void  insert(BinarySearchTree root, int data){
            if (root.data < data){
                if (root.right == null){
                    root.right = new BinarySearchTree(data);
                }else {
                    insert(root.right,data);
                }
            }else {
                if (root.left == null){
                    root.left = new BinarySearchTree(data);
                }else {
                    insert(root.left,data);
                }
            }
        }
    
        public void delect(BinarySearchTree root , int data){
    
        }
    
        /**
         * 中序遍历 左根右
         * @param root
         */
        public static void  inorder(BinarySearchTree root){
            if (root != null){
                inorder(root.left);
                System.out.print(root.data+" ");
                inorder(root.right);
            }
        }
    
        /**
         * 前序遍历 根左右
         * @param root
         */
        public static void preorder(BinarySearchTree root){
            if (root != null){
                System.out.print(root.data+" ");
                preorder(root.left);
                preorder(root.right);
            }
        }
    
        /**
         * 后序遍历 左右根
         * @param root
         */
        public static  void  postorder(BinarySearchTree root){
            if (root != null){
                postorder(root.left);
                postorder(root.right);
                System.out.print(root.data+" ");
            }
        }
        public void  levelroder(){
            BinarySearchTree root;
            while(front < rear){
                      root =  OutQueue();
                if (root.left != null){
                    EnQueue(root.left);
                }
                if (root.right != null){
                    EnQueue(root.right);
                }
            }
        }
    
        /**
         * 进队
         * @param root
         */
        public void EnQueue(BinarySearchTree root){
            queue[rear++] = root;
        }
    
        /**
         * 出队
         * @param
         */
        public BinarySearchTree  OutQueue(){
            System.out.print(queue[front].data+ " ");
           return  queue[front++];
        }
    
    
        public static void main(String[] args) {
            int data[] = {6,1,2,5,4,62,52,7,9,0};
           BinarySearchTree root =  new BinarySearchTree(data[0]);
            root.EnQueue(root);
            for (int i = 1 ; i< data.length; i++){
                root.insert(root,data[i]);
            }
            System.out.println("中序遍历:");
                inorder(root);   //对方法的直接调用,不用示例对象调用,方法需要设置为静态方法
            System.out.println("\n"+"前序遍历:");
                preorder(root); //前序
            System.out.println("\n"+"后序遍历:");
                postorder(root); //后序
            System.out.println("\n"+"层序遍历:");
                 root.levelroder();
        }
    }
    
    
  • 以下回答来自chatgpt:

    Java中继承的过程中,变量在内存中的分配会随着继承关系的建立而改变。在 Java 中,每个对象都有一个指向其类的引用,即实例变量在内存中的位置是确定的,但是变量继承关系的建立会影响其变量的访问范围。在继承过程中,子类不仅可以访问自己的成员变量,还可以访问父类的成员变量。

    下面代码使用类似C语言的方式对Java中的变量分配进行了实验:

    class A {
        public int i = 10;
    }
    
    class B extends A {
        public int j = 20;
    }
    
    public class Main {
        public static void main(String[] args) {
            A aa = new B();
            B bb = new B();
            System.out.println(aa.i);
            System.out.println(bb.j);
            System.out.println(&(aa.i)); // 编译报错
            System.out.println(&(bb.j)); // 编译报错
            System.out.println(&(bb.i)); // 编译报错
        }
    }
    

    通过上面的代码可以发现: - 子类对象可以指向父类对象, aa 是 A 类型的引用指向了实际的 B 类型的实例。 - 在 Java 堆中,父类的实例先被创建,然后才能创建子类的实例。因此,在打印 aa.i 和 bb.j 的结果时都能够输出正确的值。 - Java 语言不允许使用 & 操作符取得变量地址,因此编译器会报错。 - 对于 bb.i 的地址,在 Java 中也是无法访问的,因为 i 是从 A 类继承而来的,Java 语言并不提供求解对象成员变量的地址的功能。

    因此,对于Java中继承过程中变量的内存分配问题,需要理解不同类之间的继承关系和访问权限,具体实现将会影响变量的内存分配位置。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^