😉😉 学习交流群:
✅✅1:这是孙哥suns给大家的福利!
✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料
🥭🥭3:QQ群:583783824 📚📚 工作微信:BigTreeJava 拉你进微信群,免费领取!
🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞
💞💞5:以上内容,进群免费领取呦~ 💞💞💞💞
文章目录
一:方法的调用
1:概述
2:静态链接
3:动态链接
二:方法的绑定
1:绑定概念
2:早期绑定
3:晚期绑定
三:晚期绑定示例
1:编写代码
2:jclasslib查看内容
四:早期绑定示例
1:编写代码
2:jclasslib查看内容
五:总结说明
一:方法的调用
我们每天都在写方法的调用,但是我们能搞明白其中的原理和JVM当中的操作步骤么?这就是本文的意义。
1:概述
官方说法:
在JVM中,将符号引用转换为调用方法的直接引用这个操作是跟JVM当中方法的绑定机制息息相关的。
说人话:
上边这段话是什么意思?我这里给大家解释一下,我们javap整理完毕字节码文件之后,我们会可以在任意一个方法中查看code下的字节码指令,很多字节码指令的后边都会跟#数字这么一个概念,这个就是符号引用,这个引用指向常量池。
所谓将符号引用转换为方法的直接引用,就是将这个字节码指令后边的符号引用,转变为真实的方法。
下列中的#3就是符号引用。
public void methodB();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #6 // String methodB().....
5: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: aload_0
9: invokevirtual #7 // Method methodA:()V
12: aload_0
13: dup
14: getfield #2 // Field num:I
17: iconst_1
18: iadd
19: putfield #2 // Field num:I
22: return
从上述找一个例子的话,就是将偏移地址为9的字节码指令后边的#7这个符号引用用真实的方法字面量代替
2:静态链接
官方说法:
当一个字节码文件被装载进JVM内部时,如果被调用的目标方法在编译期可知且运行期保持不变时。这种情况下将调用方法的符号引用转换为直接引用的过程称之为静态链接。
说人话:
静态链接:这种方式在编译阶段就已经把符号引用直接转换为了直接引用。
3:动态链接
官方说法:
如果被调用的方法在编译期无法被确定下来,也就是说,只能够在程序运行期将调用方法的符号引用转换为直接引用,由于这种引用转换过程具备动态性,因此也就被称之为动态链接。
说人话:
动态链接:这种方式在运行阶段才能把符号引用直接转换为直接引用。
二:方法的绑定
1:绑定概念
绑定是一个字段、方法或者类在符号引用被替换为直接引用的过程,这仅仅发生一次。这个不论是编译器确定还是运行期确定都只会发生一次,不会修改。
对应的方法的绑定机制为:早期绑定 (Early Bindng)和晚期绑定(Late Binding)。
2:早期绑定
官方说法:
早期绑定就是指被调用的目标方法如果在编译期可知,且运行期保持不变时即可将这个方法与所属的类型进行绑定,这样一来,由于明确了被调用的目标方法究竟是哪一个,因此也就可以使用静态链接的方式将符号引用转换为直接引用。
说人话:
早期绑定是和我们的静态绑定相对应的。
3:晚期绑定
官方说法:
如果被调用的方法在编译期无法被确定下来,只能够在程序运行期根据实际的类型绑定相关的方法,这种绑定方式也就被称之为晚期绑定
说人话:
晚期绑定是和我们的动态绑定相对应的。
三:晚期绑定示例
1:编写代码
class Animal {
public void eat(){
System.out.println("动物进食");
}
}
interface Huntable{
void hunt();
}
class Dog extends Animal implements Huntable{
@Override
public void eat(){
System.out.println("狗吃骨头");
}
@Override
public void hunt() {
System.out.println("捕食耗子,多管闲事");
}
}
class Cat extends Animal implements Huntable{
@Override
public void eat(){
System.out.println("猫吃鱼");
}
@Override
public void hunt() {
System.out.println("捕食耗子,天经地义");
}
}
public class AnimalTest{
public void showAnimal(Animal animal){
animal.eat();//晚期绑定
}
public void showHunt(Huntable h){
h.hunt();//晚期绑定
}
}
2:jclasslib查看内容
四:早期绑定示例
1:编写代码
class Animal {
public void eat(){
System.out.println("动物进食");
}
}
interface Huntable{
void hunt();
}
class Dog extends Animal implements Huntable{
@Override
public void eat(){
super.eat();//早期绑定
System.out.println("狗吃骨头");
}
@Override
public void hunt() {
System.out.println("捕食耗子,多管闲事");
}
}
class Cat extends Animal implements Huntable{
public Cat(){
super();//早期绑定
}
public Cat(String name){
this();//早期绑定
}
@Override
public void eat(){
System.out.println("猫吃鱼");
}
@Override
public void hunt() {
System.out.println("捕食耗子,天经地义");
}
}
public class AnimalTest{
public void showAnimal(Animal animal){
animal.eat();//晚期绑定
}
public void showHunt(Huntable h){
h.hunt();//晚期绑定
}
}
2:jclasslib查看内容
光标放到cat这个类上查看他的jclasslib
invokeSpecial是早期绑定字节码指令,invokevirtual是晚期绑定的字节码指令。
五:总结说明
随着高级语言的横空出世,类似于Java一样的基于面向对象的编程语言如今越来越多,尽管这类编程语言在语法风格上存在一定的差别,但是它们彼此之间始终保持着一个共性,那就是都支持封装、继承和多态等面向对象特性
既然这一类的编程语言具备多态特性,那么自然也就具备早期绑定和晚期绑定两种绑定方式。
Java中任何一个普通的方法其实都具备虚函数的特征,也就是运行期才能确定下来,它们相当于c++语言中的虚函数 (c++中则需要使用关键字virtual来显式定义)。
如果在Java程序中不希望某个方法拥有虚函数的特征时,则可以使用关键字final来标记这个方法。也就是一个方法不想被晚期绑定,直接把他给final修饰即可。
文章目录
一:通信中地址简介
1:地址的唯一性
(一):唯一性狭义概念
(二):唯一性广义概念
2:地址的层次性
(一):地址分层的意义
(二):MAC地址优劣
(三):IP地址的便利
一:通信中地址简介
通信传输中,发送端和接收端可以被视为通信主体。它们都能由一个所谓“地址”的信息加以标识出来。当人们使用电话时,电话号码就相当于“地址”。当人们选择写信时,通信地址加上姓名就相当于“地址”。
在计算机通信当中,这种地址的概念显得要复杂一些。因为在实际的网络通信当中,每一层的协议所使用的地址都不尽相同。TCP/IP 通信中使用 MAC 地址、IP 地址等信息作为地。甚至在应用层中,可以将电子邮件地址作为网络通信的地址。
1:地址的唯一性
(一):唯一性狭义概念
一个地址必须明确地表示一个主体对象。在同一个通信网络中不允许有两个相同地址的通信主体存在。这也就是地址的唯一性。
(二):唯一性广义概念
到此为止,读者可能会有一个疑问。前面提到,在同一个通信网络中不允许有两个相同地址的通信主体存在。这在单播通信中还好理解,因为通信两端都是单一的主机。那么对于广播、多播、任播通信该如何理解呢?岂不是通信接收端都被赋予了同一个地址?其实,在某种程度上,这样理解有一定的合理性。在上述这些通信方式中,接收端设备可能不止一个。为此,可以对这些由多个设备组成的一组通信赋予同一个具有唯一特性的地址,从而可以避免产生歧义,明确接收对象。
举个简单的多播的例子。某位老师说:“一年一班的同学们请起立!”其中“一年一班”实际上就明确地指代了目对象。此时,“一年一班”就是这一次“多”的目标地址,具有唯一性。
再举一个任播的例子。老师又说:“一年一班的哪位同学过来把你们班的学习资取走!”“一哪同”(任意一位同学)就成为了此次“任”的目地址有一性。
2:地址的层次性
(一):地址分层的意义
当地址总数并不是很多的情况下,有了唯一地址就可以定位相互通信的主体。然而,当地址的总数越来越多时,如何高效地从中找出通信的目标地址将成为一个重要的问题。为此人们发现地址除了具有唯一性还需要具有层次性。其实,在使用电话和信件通信的过程当中,早已有了地址分层这种概念。例如,电话号码包含国家区号和国内区号,通信地址包含国名、省名、市名和区名等。正是有了这种层次分类才能更加快速地定位某一个地址。
MAC 地址和 IP 地址在识一个通信主体时虽然都具有唯一性,但是它们当中只有 IP 地址具有层次性。
(二):MAC地址优劣
MAC 地址由设备的制造厂商针对每块网卡进行分别指定。人们可以通过制造商识别号、制造商内部产品编号以及产品通用编号确保 MAC 址的唯一性。然而,人们无法确定哪家厂商的哪个网卡被用到了哪个地方。虽然 MAC 地址中的制造商识别号、产品编号以及通用编号等信息在某种度上也具有一定的层次性但是对于寻找地址并没有起到任何作用,所以不能算作有层次的地址。正因如此虽然 MAC 地址是真正负责最终通信的地址,但是在实际寻址过中,IP 地址却必不可少。
(三):IP地址的便利
那么IP 地址又是怎样实现分层的呢?一方面,IP地址由网络号和机号两部分组成。即使通信主体的IP 地址不同,若主机号不同,网络号相同,说明它们处于同一个网段。通常,同处一个网段的主机也都属于同一个部门或集团组织。另方面,网络号相同的主机在组织结构、提供商类型和地域分上都比较集中也为 IP 寻址带来了极大的方便。这也是为什么说 IP 地址具有层次性的原因。
网络传输中,每个节点会根据分组数据的地址信息,来判断该报文应该由哪个网卡发送出去。为此,各个地址会参考一个发出接口列表。在这一点上 MAC 寻址与IP 寻址是一样的。只不过 MAC 寻址中所参考的这张表叫做地址转发表,而IP寻址中所参考的叫做路由控制表。MAC 地址转发表中所记录的是实际的 MAC地址本身,而路由表中记录的 IP 地址则是集了之后的网络号
文章来源:https://www.toymoban.com/news/detail-730901.html
文章来源地址https://www.toymoban.com/news/detail-730901.html
到了这里,关于详解TCP/IP协议第五篇:详细介绍网络传输中的地址的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!