java中父类与子类, 不同的两个类中的因为构造函数由于递归调用导致栈溢出问题

简介:
/*
对于类中对成员变量的初始化和代码块中的代码全部都挪到了构造函数中,
并且是按照java源文件的初始化顺序依次对成员变量进行初始化的,而原构造函数中的代码则移到了构造函数的最后执行
*/
import static java.lang.System.out;

public class PersonDemo
{
    public static void main(String[] args)
    {
         //*********测试父类与子类之间的循环调用的问题
        out.println("main1");

        Father f = new Father();
        
        out.println("main2");
        
        f.show();
        
        out.println("main3");

        //*********测试两个无关类的循环调用的问题               
              
                MyClass11 m1=new MyClass11();
            m1.myOut();
    }
}

class Father
{
    public Son s ; //=new Son();
        
        /*
              public Song s= new Son(), 注意在这里进行初始化操作相当于在构造函数中进行初始化,会导致栈溢出, why?
              在主函数中我们产生了一个Father对象, 然后在new一个Son对象的过程中,Son对象调用其父类的构造方法来完成
              一些子类中包含父类成员的初始化,最终导致了循环调用,最终栈溢出
        */
    public newSon ns =null; // new newSon();
    
    public Father()
    {
        this(10);
        System.out.println("Father");
    }

    public Father(int a)
    {
        //this();很显然, 加上这一句就会形成构造函数递归调用!哈哈。。。
    }
    
    public void show()
    {
        s = new Son();
                /*
              如果我们将 s 的赋值操作放在这里, 也就是去掉 public Son s = new Son()的初始化,这样就不会导致栈溢出了
                    看一看也就会明白了, new Son()时会调用父类Father的构造方法来完成Son的一些成员的初始化,但是其父类构造
                    函数中没有行循环调用!
                */
        ns = new newSon();
        
        System.out.println("father show");

        s.show();
        ns.show();
    }
    
    public class newSon extends Father//内部类同样会导致上面的问题!
    {
        public newSon()
        {
            System.out.println("newSon");
        }
        
        public void show()
        {
            System.out.println("newSon show");
        }
    }
}

class Son extends Father
{
    public int a = 20;
    
    public Son()
    {
        super();
        System.out.println("Son");
    }
    
    public void show()
    {
        System.out.println("Son show");
    }
}

class MyClass11{
  
    MyClass22 m2;
   //MyClass22 m2=new MyClass22();//这样写会导致循环调用问题
   
   public MyClass11(){
       //m2=new MyClass22();//这样写和上面的错误是一样的
   }
   public void show(){
      System.out.println("This MyClass11");
   }
   public void myOut(){
       m2=new MyClass22();//m2的赋值放在这里
       m2.show();
   }
}

class MyClass22{
   
   MyClass11 m1;
   public MyClass22(){
       m1=new MyClass11();//移位main()函数中没有定义MyClass22的对象,所以这句赋值不会导致循环调用的问题,只需要将MyClass11中的赋值操作更改一下就好了
   }
   public void show(){
      System.out.println("This MyClass22");
   }
   public void myOut(){
       m1.show();
   }
}









本文转自 小眼儿 博客园博客,原文链接:http://www.cnblogs.com/hujunzheng/p/3813599.html,如需转载请自行联系原作者
目录
相关文章
|
2天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
23 3
|
6天前
|
Java 编译器
Java Character 类
4月更文挑战第13天
|
7天前
|
存储 Java
Java基础教程(7)-Java中的面向对象和类
【4月更文挑战第7天】Java是面向对象编程(OOP)语言,强调将事务抽象成对象。面向对象与面向过程的区别在于,前者通过对象间的交互解决问题,后者按步骤顺序执行。类是对象的模板,对象是类的实例。创建类使用`class`关键字,对象通过`new`运算符动态分配内存。方法包括构造函数和一般方法,构造函数用于对象初始化,一般方法处理逻辑。方法可以有0个或多个参数,可变参数用`类型...`定义。`this`关键字用于访问当前对象的属性。
|
11天前
|
Java Shell
Java 21颠覆传统:未命名类与实例Main方法的编码变革
Java 21颠覆传统:未命名类与实例Main方法的编码变革
12 0
|
11天前
|
Java
Java 15 神秘登场:隐藏类解析未知领域
Java 15 神秘登场:隐藏类解析未知领域
15 0
|
13天前
|
安全 Java
append在Java中是哪个类下的方法
append在Java中是哪个类下的方法
21 9
|
13天前
|
JavaScript Java 测试技术
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
30 0
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
|
4天前
|
安全 Java
深入理解 Java 多线程和并发工具类
【4月更文挑战第19天】本文探讨了Java多线程和并发工具类在实现高性能应用程序中的关键作用。通过继承`Thread`或实现`Runnable`创建线程,利用`Executors`管理线程池,以及使用`Semaphore`、`CountDownLatch`和`CyclicBarrier`进行线程同步。保证线程安全、实现线程协作和性能调优(如设置线程池大小、避免不必要同步)是重要环节。理解并恰当运用这些工具能提升程序效率和可靠性。
|
5天前
|
安全 Java
java多线程(一)(火车售票)
java多线程(一)(火车售票)
|
5天前
|
安全 Java 调度
Java并发编程:深入理解线程与锁
【4月更文挑战第18天】本文探讨了Java中的线程和锁机制,包括线程的创建(通过Thread类、Runnable接口或Callable/Future)及其生命周期。Java提供多种锁机制,如`synchronized`关键字、ReentrantLock和ReadWriteLock,以确保并发访问共享资源的安全。此外,文章还介绍了高级并发工具,如Semaphore(控制并发线程数)、CountDownLatch(线程间等待)和CyclicBarrier(同步多个线程)。掌握这些知识对于编写高效、正确的并发程序至关重要。