jvm-第六节方法调用

奋斗吧
奋斗吧
擅长邻域:未填写

标签: jvm-第六节方法调用 Java博客 51CTO博客

2023-07-12 18:24:22 31浏览

jvm-第六节方法调用,jvm-第六节方法调用本篇知识点概况方法调用方法调用的流程方法调用的字节码虚方法非虚方法接口调用java的语法糖以及实现泛型stream方法调用方法调用相关知识方法调用的流程方法查找,通过符号引用找到该方法方法入栈,将当前方法的局部变量表,操作数栈压入栈中,保存当前的方法状态参数传递:将调用方法传递数值拷入到被调用方法的操作数栈中方法执行返回值处理方法出栈方法调用的字节码指令invokestati

jvm-第六节方法调用

本篇知识点概况

  1. 方法调用
  1. 方法调用的流程
  2. 方法调用的字节码
  3. 虚方法
  4. 非虚方法
  5. 接口调用
  1. java的语法糖以及实现
  1. 泛型
  2. stream

方法调用

  1. 方法调用相关知识
  1. 方法调用的流程
  1. 方法查找,通过符号引用找到该方法
  2. 方法入栈,将当前方法的局部变量表,操作数栈压入栈中,保存当前的方法状态
  3. 参数传递:将调用方法传递数值拷入到被调用方法的操作数栈中
  4. 方法执行
  5. 返回值处理
  6. 方法出栈
  1. 方法调用的字节码指令
  1. invokestatic 调用静态方法
  2. invokespecial调用私有实例,构造器,super关键字
  3. invokevirtual调用非私有实例方法
  4. invokeinterface调用非私有接口
  5. invokedynamic调用动态方法
  1. 虚方法
  1. 虚方法的定义:非 非虚方法就是虚方法,比如呗invokevitual,invokeinterface调用的方法
  2. 分派: 这个和多态有关系,多态涉及到重载和重写
  1. 静态分派:主要通过重载实现,发生在编译期间,编译器根据方法调用的静态类型选择合适的重载方法,比如下面的例子
public class Example {
    public static void test(int x) {
        System.out.println("test(int): " + x);
    }
    
    public static void test(double x) {
        System.out.println("test(double): " + x);
    }
    
    public static void main(String[] args) {
        int a = 10;
        double b = 3.14;
        test(a);    // 静态类型为int,调用test(int)方法
        test(b);    // 静态类型为double,调用test(double)方法
    }
}

  1. 动态分派:主要通过重写实现,发生在运行期间,运行时根据对象的实际类型确定调用那个方法
public class Animal {
    public void makeSound() {
        System.out.println("Animal makes sound.");
    }
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks.");
    }
}

public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat meows.");
    }
}

public class Example {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();
        
        animal1.makeSound();    // 输出 "Dog barks."
        animal2.makeSound();    // 输出 "Cat meows."
    }
}
  1. 方法表:动态分派是一个执行非常频繁的动作,jvm为了优化建立了虚方法表,代替元数据查找提高性能
  2. jvm-第六节方法调用_虚方法


  1. 接口调用:invokeinterface,invokevirtual,
  2. jvm-第六节方法调用_List_02

  3. lambda:invokedynamic这个指令是执行动态方法的,比如lamda表达式,而且这东西比反射快,因为他用了方法句柄methodhandle
  4. jvm-第六节方法调用_List_03

  1. 非虚方法:如果方法在编译期就能确定具体的调用版本,在运行时不可变,比如能被invokestatic,invokerspecial指令调用的,以及final修饰的方法;具体如下图

Java语法糖以及实现

  1. Java的泛型:既参数化类型,允许定义类,接口时使用类型化参数,以便在编译期进行类型安全检查,用他的好处是提高代码的重用性。比如下面这段代码
Box<Integer> box = new Box<>();
box.setValue(10);
int value = box.getValue();  // 不需要进行类型转换

public interface List<E> {
    void add(E element);
    E get(int index);
}

public class Utils {
    public static <T> T getLast(List<T> list) {
        if (list.isEmpty()) {
            return null;
        }
        return list.get(list.size() - 1);
    }
}

public void printList(List<?> list) {
    for (Object element : list) {
        System.out.println(element);
    }
}
  1. 有一些约定俗成的类型参数名称
  1. E-元素
  2. K-键
  3. V-值
  4. N-数字
  5. T-类型
  6. S-类型
  7. U-类型
  8. V-类型
  1. stream
  1. 什么是steam:是处理集合数据的抽象概念,提供了一种函数式的方式对集合进行各种操作
  2. 看一下steam的应用
  3. jvm-第六节方法调用_方法调用_04

  4. steam操作的分类:它分为俩类,终结操作和中间操作
  1. 中间操作跟着零个或者多个中间操作
  2. 中间操作分为有状态和无状态
  3. 终结操作只会执行一次
  4. 终结操作分为短路和非短路
  1. 看例子
  2. 在Java中,Stream是Java 8引入的一种用于处理集合数据的抽象概念。Stream提供了一种流式操作的方式,可以对数据进行一系列的中间操作和终结操作。 中间操作(Intermediate Operations)是指对Stream中的元素进行处理或转换的操作,它们会返回一个新的Stream作为结果,并且可以链式调用。常见的中间操作有filter、map、sorted等。以下是一些中间操作的代码示例:
  1. filter操作:用于过滤Stream中的元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> evenNumbers = numbers.stream()
                                   .filter(n -> n % 2 == 0)
                                   .collect(Collectors.toList());
  1. map操作:用于对Stream中的每个元素进行转换。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream()
                                 .map(String::length)
                                 .collect(Collectors.toList());
  1. sorted操作:用于对Stream中的元素进行排序。
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 6, 3, 9, 4, 7);
List<Integer> sortedNumbers = numbers.stream()
                                     .sorted()
                                     .collect(Collectors.toList());

终结操作(Terminal Operations)是指对Stream进行最终处理的操作,它们会返回一个最终的结果,如集合、值、或副作用。常见的终结操作有collect、forEach、reduce等。以下是一些终结操作的代码示例:

  1. collect操作:用于将Stream中的元素收集到一个集合中。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> collectedNumbers = numbers.stream()
                                        .filter(n -> n % 2 == 0)
                                        .collect(Collectors.toList());
  1. forEach操作:用于对Stream中的每个元素执行指定的操作。
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream()
     .forEach(System.out::println);
  1. reduce操作:用于将Stream中的元素按照指定的操作进行聚合。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> sum = numbers.stream()
                               .reduce((a, b) -> a + b);

这只是一些常见的中间操作和终结操作的示例,Stream还提供了许多其他的操作方法,如distinct、limit、skip等,可以根据具体需求选择使用。通过使用Stream的中间操作和终结操作,可以在简洁、高效的代码中对集合数据进行处理和操作。


好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695