likes
comments
collection
share

java 重载重写思想

作者站长头像
站长
· 阅读数 45

方法重载

重载介绍

方法重载指同一个类中定义的多个方法之间的关系,满足下列条件的多个方法相互构成重载:

  1. 多个方法在同一个类
  2. 多个方法具有相同的方法名
  3. 多个方法的参数不相同,类型不同或者数量不同

重载仅对应方法的定义,与方法的调用无关,调用方式参照标准格式

重载仅针对同一个类中方法的名称与参数进行识别,与返回值无关,不能通过返回值来判定两个方法是否构成重载

原理:JVM → 运行机制 → 方法调用 → 多态原理

public class MethodDemo {
	public static void hugh(int a) {
		//方法体
	}
    
	public static int hugh(int a) { /*错误原因:重载与返回值无关*/
		//方法体
	}
    
    public static void hugh(int a, int b) {/*正确格式*/
		//方法体
	}
}

方法选取

重载的方法在编译过程中即可完成识别,方法调用时 Java 编译器会根据所传入参数的声明类型(注意与实际类型区分)来选取重载方法。选取的过程共分为三个阶段:

  • 一阶段:在不考虑对基本类型自动装拆箱 (auto-boxing,auto-unboxing),以及可变长参数的情况下选取重载方法
  • 二阶段:如果第一阶段中没有找到适配的方法,那么在允许自动装拆箱,但不允许可变长参数的情况下选取重载方法
  • 三阶段:如果第二阶段中没有找到适配的方法,那么在允许自动装拆箱以及可变长参数的情况下选取重载方法

如果 Java 编译器在同一个阶段中找到了多个适配的方法,那么会选择一个最为贴切的,而决定贴切程度的一个关键就是形式参数类型的继承关系,一般会选择形参为参数类型的子类的方法,因为子类时更具体的实现

public class MethodDemo {
    void invoke(Object obj, Object... args) { ... }
    void invoke(String s, Object obj, Object... args) { ... }

    invoke(null, 1); 	// 调用第二个invoke方法,选取的第二阶段
    invoke(null, 1, 2); // 调用第二个invoke方法,匹配第一个和第二个,但String是Object的子类
    
    invoke(null, new Object[]{1}); // 只有手动绕开可变长参数的语法糖,才能调用第一个invoke方法
    							   // 可变参数底层是数组,JVM->运行机制->代码优化
}

因此不提倡可变长参数方法的重载


继承重载

除了同一个类中的方法,重载也可以作用于这个类所继承而来的方法。如果子类定义了与父类中非私有方法同名的方法,而且这两个方法的参数类型不同,那么在子类中,这两个方法同样构成了重载

  • 如果这两个方法都是静态的,那么子类中的方法隐藏了父类中的方法
  • 如果这两个方法都不是静态的,且都不是私有的,那么子类的方法重写了父类中的方法,也就是多态

参数传递

Java 的参数是以值传递的形式传入方法中

值传递和引用传递的区别在于传递后会不会影响实参的值:值传递会创建副本,引用传递不会创建副本

  • 基本数据类型:形式参数的改变,不影响实际参数

    每个方法在栈内存中,都会有独立的栈空间,方法运行结束后就会弹栈消失

    public class ArgsDemo01 {
    	public static void main(String[] args) {
    		int number = 100;
    		System.out.println("调用change方法前:" + number);//100
    		change(number);
    		System.out.println("调用change方法后:" + number);//100
    	}
    	public static void change(int number) {
    		number = 200;
    	}
    }
    
  • 引用类型:形式参数的改变,影响实际参数的值

    引用数据类型的传参,本质上是将对象的地址以值的方式传递到形参中,内存中会造成两个引用指向同一个内存的效果,所以即使方法弹栈,堆内存中的数据也已经是改变后的结果

    public class PassByValueExample {
        public static void main(String[] args) {
            Dog dog = new Dog("A");
            func(dog);
            System.out.println(dog.getName());	// B
        }
        private static void func(Dog dog) {
            dog.setName("B");
        }
    }
    class Dog {
        String name;//.....
    }
    
转载自:https://juejin.cn/post/7173654598169657375
评论
请登录