本例根据一个实例来说明类方法和实例方法调用的区别,以及不同修饰符下的属性调用的区别,并对这种区别作出解释。
父类定义:
public class Parent{
public static String name = "父类的名字,静态常量";
public final int age = 40;
public String birth = "父类生日,变量";
public static void sayHello(){
System.out.println("父类的类方法,Hello Parent~");
}
public void sayBye(){
System.out.println("父类的实例方法,Bye Parent~");
}
}
子类定义:
public class Son extends Parent{
public static String name = "子类名字,静态变量";
public final int age = 20;
public String birth = "子类生日,变量";
public static void sayHello(){
System.out.println("子类的类方法,Hello Child!");
}
public void sayBye(){
System.out.println("子类的实例方法,Bye Child!");
}
public static void main(String[] args){
//1
Parent obj1 = new Son();
System.out.println(obj1.name);
System.out.println(obj1.age);
System.out.println(obj1.birth);
obj1.sayHello();
obj1.sayBye();
}
}
输出结果:
引用
父类的名字,静态常量
40
父类生日,变量
父类的类方法,Hello Parent~
子类的实例方法,Bye Child
主函数中声明了对Parent的引用obj1,这个引用指向Son的对象,即实际对象是利用new Son()所创建的实例。
上例中,obj1对调用了Parent类的静态方法sayHello(),而调用了Son类的实例方法sayHello()。对类方法和实例方法调用的区别,《深入Java虚拟机》中有这样一段话可以解释:
引用
当JVM调用一个类方法时,它会基于对象引用的类型(通常在编译时可知)来选择所调用的方法。相反,当JVM调用一个实例方法是,它会基于实际对象的类(只能在运行时得知)来选择所调用的方法。
对象引用obj1的类型Parent自加载进入JVM之后便在内存的方法区维护了静态方法,而Son类的实例方法sayBye()是在被实际对象调用的时候才动态连接的。
基于上面分析可以推测,因为类在方法区中还维护了字段信息、类(静态)变量、常量池,JVM调用一个字段时,它将基于对象引用的类型来选择所调用的字段,故obj1调用的字段皆来自于父类Parent。
注:常量池:常量池就是该类型所用常量的一个有序集合,包括直接常量(string、integer和floating point常量)和对其他类型、字段和方法的符号引用。池中的数据项就像数组一样是通过索引访问的,因为常量池存储了相应类型所用到的所有类型、字段和方法的符号引用,所以他在java程序的动态连接性中起到核心作用。
分享到:
相关推荐
这篇博文将带你入门Java反射,并通过属性和方法的调用来实践这一概念。 首先,理解反射的基础概念。在Java中,`Class`类代表了运行时的类信息。通过`Class`对象,我们可以获取到类的名称、构造器、方法和字段。例如...
4. 调用方法:对获取到的`Method`对象,调用`invoke()`方法,传入对象实例和方法参数。 下面是一个简单的示例,演示了如何动态加载一个类并调用其方法: ```java public class Tafcm01 { public static void main...
当子类实例化时,会调用抽象类中的构造方法进行初始化。 在Java中,实例化抽象类的一种常见方式是通过子类继承并实现抽象方法。假设有一个抽象类`AbstractBase`: ```java public abstract class AbstractBase { ...
6. **静态方法调用实例成员**:静态方法可以直接调用类的静态字段,但不能直接访问实例字段,因为它们没有对象上下文。如果需要访问实例字段,通常需要通过传递对象实例作为参数。 7. **多态(Polymorphism)**:...
- 性能开销:反射涉及类型信息的查找和解析,比直接调用成员方法或访问字段慢得多。 - 安全性和性能问题:过度使用反射可能会引入安全漏洞,并影响应用程序的性能。 #### 5. 实践中的注意事项 - **性能考量**:在...
这个特性使得Java具有了更高的灵活性,能够处理一些在编译时无法确定的对象和方法调用。 在给定的代码中,`TestRef` 类展示了如何使用Java反射调用方法。首先,我们创建了一个 `Foo` 类,它有一个私有字符串成员...
在C#编程语言中,类(Class)是面向对象编程的核心概念,它是创建对象...了解并熟练掌握类、属性、字段和方法对于编写高效且易于维护的C#代码至关重要。通过实践这些基本概念,开发者能够构建出复杂且功能丰富的应用。
反射是Java提供的一种机制,它允许程序在运行时检查类、接口、字段和方法的信息,甚至可以创建和操作对象。`java.lang.reflect`包提供了多种类和接口来支持反射,如`Class`、`Constructor`、`Method`和`Field`。例如...
在Java编程语言中,反射(Reflection)是一种强大的工具,它允许程序在运行时检查和操作类、接口、字段和方法等对象。枚举(Enumeration)是Java中的一个特殊类类型,用于定义一组常量。本项目"test-enum-demo-...
总的来说,Java动态调用方法通过反射机制实现了运行时对类和方法的动态操作,这在许多场合都有用武之地,如插件系统、自动化测试、元编程等。然而,由于反射的特性,也需要注意其可能带来的安全问题和性能影响。在...
总结来说,C#中的字段、属性、方法和事件构成了类的主要成员,它们共同作用于对象的描述、状态管理、行为实现和外部通信,是构建复杂应用程序的基础。理解和熟练运用这些概念对于成为一名高效的C#开发者至关重要。
泛微接口说明与调用实例主要涵盖了泛微协同办公系统中的接口规范,这些接口主要用于不同模块的数据交互和服务集成。在企业信息化建设中,接口的合理使用可以实现各个系统的无缝对接,提高工作效率。以下是对各文件...
在Windows Presentation Foundation (WPF) 中,继承是面向对象编程的一个关键特性,它允许子类继承父类的属性、字段和方法,以便扩展或重写它们。标题“WPF继承_子类继承父类,实现跨类调用方法”表明我们将讨论如何...
Java反射是Java编程语言中的一个强大特性,它允许在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这个特性使得Java具有了高度的灵活性,常用于框架开发、插件系统、元编程等...
例如,我们可以创建一个包含静态字段和方法的类: ```csharp public class MyClass { public static int StaticField = 0; // 静态字段 public static void StaticMethod() { // 静态方法 Console.WriteLine("这...
本篇文章将详细探讨如何在C#中调用C++的DLL,并通过一个实例代码进行演示。 首先,我们需要了解C#调用C++DLL的基本原理。.NET框架提供了一种称为P/Invoke(Platform Invoke)的技术,允许C#代码调用非托管代码,如...
Java反射是Java语言提供的一种强大的动态类型特性,它允许程序在运行时检查类、接口、字段和方法的信息,并且能够动态地创建对象和调用方法。这个能力使得开发者可以突破静态类型的束缚,实现一些在编译时期无法完成...
abstract修饰符可修饰字段、方法和类 B. 抽象方法的body部分必须用一对大括号{ }包住 C. 声明抽象方法,大括号可有可无 D. 声明抽象方法不可写出大括号 2. 如下代码 public class Test { public int aMethod() {...
在这个例子中,`SharedValue` 是一个静态字段,可以被 `IncrementShared` 和 `DecrementShared` 方法所访问和修改,无论创建多少个 `MyClass` 的实例,`SharedValue` 的值都是共享的。 静态字段常用于计数器、全局...