多态的一个表现

子类类型赋值给父类 Father f1 = New Son()

调用子类方法报错。 调用父类方法OK。这个就是多态

一个对象能用什么方法,并不是取决于 它有什么方法。

而是取决于引用变量的类型(也就是取决于它声明的类型,Father类型)

它能够用的方法,一定是Father中的方法。

通过反射来获取整体的对象。这个整体的对象我们称之为:类对象。

怎么获取这个类对象呢? 通过f1.getClass()来获取类对象

字节码对象

package part;

public class Java01 {
public static void main(String[] args) {
User u1 = new User();
u1.test1();
// 通过 u1.getClass() 来获取:类对象
// Class 是java.lang包下的。所以不需要再导入了。
// 这里的aClass对象就是java中的字节码文件
// 所谓的字节码文件:就是我们使用javac编译后的那个源码文件
Class<? extends User> aClass = u1.getClass();
}
} class User{
public void test1(){
System.out.println("test1");
}
} class Child extends User{
public void test2(){
System.out.println("test2");
}
}

获取类中的属性,方法以及其他信息

package part;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; public class Java01 {
public static void main(String[] args) {
User u1 = new User();
// 通过 u1.getClass() 来获取:类对象
// Class 是java.lang包下的。所以不需要再导入了。
// 这里的aClass对象就是java中的字节码文件
// 所谓的字节码文件:就是我们使用javac编译后的那个源码文件
// 类对象
Class<? extends User> aClass = u1.getClass();
// 获取类的完整名称,包含包名 输出:part.User
System.out.println(aClass.getName());
// 获取类的名称 输出:User
System.out.println(aClass.getSimpleName());
// 获取类的包的信息 输出:package part
System.out.println(aClass.getPackage());
// 获取类的包名 输出:part
System.out.println(aClass.getPackage().getName()); Class<?> superclass = aClass.getSuperclass();
// 获取类的父类 输出:class java.lang.Object
System.out.println(superclass); // 获取类的接口,可能存在多个,因此是一个数组的哈。
Class<?>[] interfaces = aClass.getInterfaces();
// 输出0,因为我们这里没有实现接口的哈
System.out.println(interfaces.length); try {
// 获取类的属性,只能获取公共(public)的属性
Field f1 = aClass.getField("xx");
// 获取类的属性,所有的权限,就是你是私有的,我也可以获取
Field f2 = aClass.getDeclaredField("aa");
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} // 获取类的所有属性,前提是这些属性都是public修饰的,是公共的,返回来的是数组
Field[] fields = aClass.getFields();
// 获取类的所有属性,就是你是私有的,我也可以获取,,返回来的是数组
Field[] declaredFields = aClass.getDeclaredFields(); try {
// 获取类中的公共的方法
Method method= aClass.getMethod("test");
// 获取类中的方法,就算是私有的也可以获取
Method methods = aClass.getDeclaredMethod("test2");
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} // 获取类中所有公共的方法,是公共的,返回来的是数组
Method[] methods = aClass.getMethods();
// 获取类中的所有方法,方法就算是私有的也可以获取,返回来的是数组
Method[] allMethods = aClass.getDeclaredMethods(); try {
// 构造方法 constructor 就是构造对象
Constructor<? extends User> constructor = aClass.getConstructor();
// 返回所有的构造方法
Constructor<?>[] constructors = aClass.getConstructors();
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} }
} class User{
public void test1(){
System.out.println("test1");
}
} class Child extends User{
public void test2(){
System.out.println("test2");
}
}

java中的类主要分为3种。

1.java核心类库中的类:string, Object

2.JVM软件平台厂商

3.我们自己写的类,比如:User,Child这些

类加载器也有3种

JDK 9+

  1. BootClassLoader 启动类加载器,如string, Object
  2. PlatformClassLoader 平台类加载器,如软件平台厂商。

    在jdk8及以前的话,这个平台类加载器变成了扩展类加载器Extension ClassLoader
  3. AppClassLoader 应用类加载器,如我们自己写的类

    类加载器在加载时也是有顺序的:

    java核心类库中的类(string, Object)==> 平台类(软件平台厂商) ==> 应用类加载器(自己写的类)

JDK 8 及之前是下面这3种

1.启动类加载器(Bootstrap ClassLoader)

2.扩展类加载器(Extension ClassLoader),在JDK 9+中,[扩展类加载器]变成了[平台类加载器]

3.应用类加载器(Application ClassLoader,也叫系统类加载器)

得到应用类加载器

package part;

public class Java01 {
public static void main(String[] args) {
// 获取类的信息,以前我们是通过new的形式,现在我们取到了Student这个类的信息。
Class<Student> studentClass = Student.class;
// 获取Student这个类的加载器
ClassLoader classLoader = studentClass.getClassLoader();
// 输出: sun.misc.Launcher$AppClassLoader@14dad5dc
// 得到的是:应用类加载器。为啥是应用类加载器呢?因为是我们自己写的类。所以是应用类加载器
System.out.println(classLoader);
}
} class Student { }

String类的类加载器为啥是null?

package part;

public class Java01 {
public static void main(String[] args) {
Class<String> stringClass = String.class;
ClassLoader classLoader = stringClass.getClassLoader();
// 输出null
System.out.println(classLoader);
}
} class Student { }

有些小伙伴看到这里会觉得很奇怪,为啥是null?

你不是说:string, Object 这些是启动器类吗?

按理说应该是:BootClassLoader(启动类加载器)才对。

因为:启动类加载器通常表示为null,因为它不是Java实现的。

解释一下启动类

启动类加载器是最顶层的,由原生代码实现,不继承java.lang.ClassLoader。

启动类加载器通常表示为null,因为它不是Java实现的。

得到平台类

我们可以理解为:平台类是应用类加载器的上一级的加载器。也就是说有有一个上一级的概念。

如果我们想要获取平台类的话。 通过自己写的类可以得到平台类。下面我们来尝试一下

package part;

public class Java01 {
public static void main(String[] args) {
// 获取类的信息,以前我们是通过new的形式,现在我们取到了Student这个类的信息。
Class<Student> studentClass = Student.class;
// 获取Student这个类的加载器
ClassLoader classLoader = studentClass.getClassLoader();
// 输出的是:在标准的JDK环境下(如JDK 8),输出会是:sun.misc.Launcher$ExtClassLoader@28d93b30
// JDK 9+ 由于模块化系统的引入,类加载器名称可能变为 jdk.internal.loader.ClassLoaders$PlatformClassLoader,但逻辑一致。
System.out.println(classLoader.getParent());
}
} class Student { }

在啰嗦说一下Java的类加载器层次结构

我们回忆Java的类加载器层次结构。通常,Java的类加载器分为三个层次:

启动类加载器(Bootstrap ClassLoader)、

扩展类加载器(Extension ClassLoader)、(这里根据版本不同,有所变化)

应用类加载器(Application ClassLoader,也叫系统类加载器)。

因此,启动类加载器通常表示为null,因为它不是Java实现的。

扩展类加载器负责加载JRE的扩展目录(如jre/lib/ext)中的类,而应用类加载器负责加载classpath下的类。

特别提醒:应用类加载器的父加载器是扩展类加载器,而扩展类加载器的父加载器是启动类加载器。

其中,启动类加载器是最顶层的,由原生代码实现,不继承java.lang.ClassLoader。

尾声

准备开始学习java了。

今天学习的第10天,每天都会发文章,我要卷起来。

请小伙伴们监督我,奥利给

java中反射-字节码和类加载器的更多相关文章

  1. 尚学堂 216 java中的字节码操作

    所谓的字节码操作就是操作我们已经加载的字节码 接下来我们重点来讲解javaassist类库 使用需要下载jar包,把jar包添加到对应的工程之后 package com.bjsxt.test; pub ...

  2. java中定义的四种类加载器

    1,Bootstrap ClassLoader   启动类加载器2,ExtClassLoader   扩展类加载器3,AppClassLoader   系统类加载器4,ClassLoader   类加 ...

  3. 尚学堂 217 java中的字节码操作2

    package com.bjsxt.test; @Author(name="gaoqi", year=2014) public class Emp { private int em ...

  4. jvm字节码和类加载机制

    Class类文件的结构 任何一个Class文件都对应着唯一一个类或接口的定义信息,但反过来说,类或接口并不一定都得定义在文件里(类和接口也可以用反射的方式通过类加载器直接生成) Class文件时一组以 ...

  5. Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论

    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...

  6. Java虚拟机笔记 – JVM 自定义的类加载器的实现和使用2

    1.用户自定义的类加载器: 要创建用户自己的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定类的名 ...

  7. 深入理解Java虚拟机(字节码执行引擎)

    深入理解Java虚拟机(字节码执行引擎) 本文首发于微信公众号:BaronTalk 执行引擎是 Java 虚拟机最核心的组成部分之一.「虚拟机」是相对于「物理机」的概念,这两种机器都有代码执行的能力, ...

  8. java中反射学习整理

    转载请注明:http://blog.csdn.net/j903829182/article/details/38405735 反射主要是指程序能够訪问.检測和改动它本身的状态或行为的一种能力. jav ...

  9. 深入浅出Java探针技术1--基于java agent的字节码增强案例

    Java agent又叫做Java 探针,本文将从以下四个问题出发来深入浅出了解下Java agent 一.什么是java agent? Java agent是在JDK1.5引入的,是一种可以动态修改 ...

  10. Java虚拟机--虚拟机字节码执行引擎

    Java虚拟机--虚拟机字节码执行引擎 所有的Java虚拟机的执行引擎都是一致的:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果. 运行时栈帧结构 用于支持虚拟机进行方法调用和方 ...

随机推荐

  1. Flink 1.10中idea运行出错invalid flag

    今日好奇,下载Flink 1.10的源码在本机玩一玩. 将工程按照正常流程导入IDEA后,运行flink-examples中的demo竟出现如下错误 Error:java: invalid flag: ...

  2. Java日志手机号脱敏工具类

    背景 在开发过程中,很容易将用户敏感信息,例如手机号码.身份证等,打印在日志平台.为了保护用户数据,又不影响日志的打印,需要将日志中的敏感信息进行脱敏. 效果 没看明白,强烈建议 pull项目,执行一 ...

  3. OceanBase 的探索与实践

    作者:来自 vivo 互联网数据库团队- Xu Shaohui 本文总结了目前我们遇到的痛点问题并通过 OceanBase 的技术方案解决了这些痛点问题,完整的描述了 OceanBase 的实施落地, ...

  4. Redis应用—1.在用户数据里的应用

    大纲 1.社区电商的业务闭环 2.Redis缓存架构的典型生产问题 3.用户数据在读多写少场景下的缓存设计 4.热门用户数据的缓存自动延期机制 5.缓存惊群与穿透问题的解决方案 6.缓存和数据库双写不 ...

  5. vscode本地调试gitbook

    1. windows下载安装git 2.安装nodejs 下载安装nvm https://github.com/coreybutler/nvm-windows/releases/download/1. ...

  6. vue使用less 有报错(loaderContext.getResolve is not a function)

    1.安装less npm install less-loader --save 2.main.js 引入 import less from 'less' Vue.use(less) warning:如 ...

  7. 通过云主机调用API,一键训练部署商品问答模型

    本文分享自华为云社区<[开发者空间实践指导]CodeArts IDE调用API训练商品问答模型>,作者:开发者空间小蜜蜂. 一.案例介绍 在电子商务领域,售前和售后服务是确保客户满意度和提 ...

  8. 2024年1月Java项目开发指南16:用户自由选择字段查询、是否模糊查询

    我们希望用户可以自己控制是否要模糊查询 用户可以自由的选择字段去查询. 如上图,我在前端页面准备了 多选框:决定是否模糊查询.(True or False) 下拉选择框:决定要查询关键词的所属字段 输 ...

  9. vmagent如何快速采集和转发Metrics

    vmagent如何快速采集和转发Metrics 本文介绍了vmagent的设计细节,参考自:vmagent-how-it-works VictoriaMetrics agent是一个轻量级工具,用于采 ...

  10. Solon v3.0.5 发布!(Spring 生态可以退休了吗?)

    Solon 框架! 新一代,面向全场景的 Java 应用开发框架.从零开始构建(非 java-ee 架构),有灵活的接口规范与开放生态. 追求: 更快.更小.更简单 提倡: 克制.高效.开放.生态 有 ...