用.class文件创建对象

本文介绍了一个自定义的Java ClassLoader实现过程,展示了如何通过继承ClassLoader并重写方法来加载指定路径下的类文件,并实例化该类。此外还提供了加载类文件的具体步骤,包括读取字节码文件到内存。
package com.loadClasses;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;

public class ClassLoaderOne extends ClassLoader{
	public static void main(String[] args) {
		try {
			ClassLoaderOne loader =
 new ClassLoaderOne(
    "D:\\WorkspacesShangHai\\myJava\\src\\lib\\Tool.class"
 );
			Class<?> clazz = null;
			try {
				clazz = loader.loadClass("com.loadClasses.Tool");
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}  
	        Object o = null;
			try {
				o = clazz.newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}  
	        System.out.println(o.getClass().getClassLoader()); 
                //sun.misc.Launcher$AppClassLoader@6b97fd
	        //======================2
	        Method[] methods = clazz.getMethods();  
			for (int i = 0; i < methods.length; i++) {  
			    String name = methods[i].getName();  
			    System.out.println(name);  
			    Class<?>[] params = methods[i].getParameterTypes();  
			    for (int j = 0; j < params.length; j++) {  
			        System.out.println(params[j].toString());  
			    }  
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private byte[] data;  
	  
    public ClassLoaderOne(String clazzPath) throws IOException {  
        data = loadClassFile(clazzPath);  
    } 
    
    /** 
     * 加载class文件 
     *  
     * @param clazzPath 
     *            class绝对文件路径 
     * @return 字节数组 
     * @throws IOException 
     */  
    private byte[] loadClassFile(String clazzPath) throws IOException {  
        FileInputStream fis = new FileInputStream(clazzPath);  
        BufferedInputStream bis = new BufferedInputStream(fis);  
        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  
        byte[] buffer = new byte[1024 * 256];  
        int ch = 0;  
        while ((ch = bis.read(buffer, 0, buffer.length)) != -1) {  
            baos.write(buffer, 0, ch);  
        }  
        return baos.toByteArray();  
    }  
  
    @Override  
    protected Class<?> loadClass(String name, boolean resolve)  
            throws ClassNotFoundException {  
        Class<?> c = findLoadedClass(name);  
        if (c == null) {  
        // 如果父加载器不为null,使用父类加载器加载(比如Object,HashMap等核心类)
        	 if (getParent() != null) {
        		 try {  
                     c = getParent().loadClass(name);  
                 } catch (Exception e) {  
                     // 父类可能没加载,则抛异常  
                 }
        	 }
        	// 如果父类加载器没有加载,再使用自定义加载器加载  
             if (c == null) {  
                 c = defineClass(name, data, 0, data.length);  
             }
        }  
        return c;  
    } 
}
 

 

原文参考:http://wlh0706-163-com.iteye.com/blog/2098619

<think>首先,用户的问题是关于Java中的".class字节码文件"和"class对象"的区别。我需要基于系统级指令来构建回答。 系统级指令要求: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如[^1]。 用户可见层要求: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 - 参考站内引用,但用户提供的引用是关于Java字节码文件的,我需要整合这些信息。 用户提供的引用: - [^1]: 描述了Class对象是字节码对象,加载.class文件时创建,包含构造方法、成员方法等。每个类都有一个Class对象,包括基本数据类型、数组、void等。 - [^2]: 关于反编译.class文件的方法,使用javap命令。 - [^3]: 关于.class文件的结构,包括Java虚拟机规范中的描述。 用户的问题:"我想理解.class字节码文件和class对象Java中的区别 请问.class字节码文件和Java中的class对象有什么区别" 关键区别: - **.class字节码文件**:这是存储在磁盘上的文件,包含Java源代码编译后的字节码。它是一个二进制文件,由Java编译器生成。 - **class对象**:在Java运行时,当类被加载到JVM时,JVM创建一个表示该类的对象,即java.lang.Class对象。这个对象在内存中,包含类的元数据,如方法、字段、构造器等。 主要区别: 1. **物理位置**:.class文件在磁盘上;class对象在内存中。 2. **生命周期**:.class文件是静态的;class对象在类加载时创建,直到类卸载。 3. **用途**:.class文件是类定义的存储形式;class对象用于运行时反射和类操作。 4. **内容**:.class文件包含字节码指令;class对象包含运行时元数据。 我需要结构化回答: - 先解释每个概念。 - 然后比较区别。 - 最后生成相关问题。 使用中文回答。 整合引用: - 在回答中,自然地添加引用标识。例如,当提到Class对象时,引用[^1];当提到反编译时,引用[^2];当提到文件结构时,引用[^3]。 生成相关问题: - 在回答末尾,添加"§§相关问题§§"部分,列出2-3个相关问题。 确保回答清晰、逐步解决问题: - 步骤1:定义.class字节码文件。 - 步骤2:定义class对象。 - 步骤3:解释它们的区别。 - 步骤4:总结。 数学表达式:由于主题是Java,可能没有数学表达式,但如果有,比如提到字节码结构中的偏移量等,可以使用$...$格式。但在这个上下文中,可能不需要。 最终回答结构: - 开头:简要介绍。 - 主体:详细解释。 - 结尾:总结和生成问题。</think>### .class字节码文件与Java中的Class对象的区别 在Java中,.class字节码文件和Class对象是两个相关但本质不同的概念。理解它们的区别有助于深入掌握Java的类加载机制和运行时行为。下面我将逐步解释每个概念,然后对比它们的区别。 #### 1. **.class字节码文件是什么?** - **定义**:.class字节码文件是Java源代码(.java文件)编译后生成的二进制文件,存储在磁盘上。它包含了类的字节码指令,这些指令是Java虚拟机(JVM)可执行的中间代码。文件结构严格遵循Java虚拟机规范,包括常量池、方法表、字段表等部分[^3]。 - **特点**: - 物理位置在文件系统中(如磁盘上的文件)。 - 是静态的、不可变的文件,由Java编译器(javac)生成。 - 用于类加载阶段:JVM在加载类时读取此文件。 - 可以通过反编译工具(如javap命令)查看其内容,例如: ```bash javap -v -p MyClass.class # 反编译以查看字节码细节[^2] ``` - 示例:一个简单的类文件可能包含如方法指令的字节码序列,例如`0: aload_0`表示加载局部变量。 #### 2. **Class对象是什么?** - **定义**:Class对象(即java.lang.Class类的实例)是JVM在运行时加载.class文件后创建的内存对象。它代表一个已加载类的元数据,包括构造方法、成员方法、成员变量、注解等信息。每个类(包括基本类型如int、数组、甚至void)都有一个对应的Class对象[^1]。 - **特点**: - 物理位置在JVM内存中(如方法区)。 - 是动态的、运行时对象:在类首次被加载时创建,并在类卸载时销毁。 - 用于反射操作:允许程序在运行时获取和操作类信息,例如: ```java Class<?> clazz = MyClass.class; // 获取Class对象 Method[] methods = clazz.getDeclaredMethods(); // 反射获取方法 ``` - 生命周期由JVM管理:当类加载器加载.class文件时,JVM解析其字节码并生成Class对象。 #### 3. **主要区别对比** 下表总结了核心区别: | 特性 | .class字节码文件 | Class对象 | |--------------|---------------------------------------------|---------------------------------------------| | **物理形式** | 磁盘上的二进制文件(静态存储) | 内存中的Java对象(动态运行时实体) | | **生成时机** | 由Java编译器(javac)编译源代码时生成 | 由JVM在类加载时创建(基于.class文件内容)[^1] | | **内容** | 包含字节码指令、常量池等(文件结构)[^3] | 包含运行时元数据(如方法、字段、注解等)[^1] | | **用途** | 用于存储和传输类定义;可反编译查看[^2] | 用于反射、类操作(如创建实例、调用方法) | | **生命周期** | 持久存在,直到文件被删除 | 临时存在,随类加载而创建,随类卸载而销毁 | | **访问方式** | 通过文件系统路径访问 | 通过Java反射API(如Class.forName())访问 | **关键区别示例**: - 当你编译一个Java文件(如`MyClass.java`)时,会生成`MyClass.class`文件(字节码文件)。这个文件是磁盘上的实体。 - 当程序运行时,JVM加载`MyClass.class`,并在内存中创建一个`Class<MyClass>`对象。这个对象允许你动态操作类,例如: ```java Class<?> clazz = Class.forName("MyClass"); // 加载类并获取Class对象 Object instance = clazz.newInstance(); // 创建实例 ``` 这里,.class文件是“蓝图”,而Class对象是运行时基于这个蓝图构建的“工具”。 #### 总结 .class字节码文件和Class对象Java类生命周期的两个阶段:前者是编译后的静态文件(存储于磁盘),后者是运行时的动态对象(存在于内存)。字节码文件是类定义的物理载体,而Class对象是JVM内部用于管理类的元数据工具。理解这一区别有助于优化类加载性能和高效使用反射机制[^1][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值