花几千上万学习Java,真没必要!(四十七)

1、类加载器(ClassLoader)负责将类的.class文件加载到Java虚拟机(JVM)中。 Java  三种内置的类加载器:

内置类加载器
Bootstrap Class Loader(引导类加载器):
JVM自带的类加载器,不是Java语言实现的,而是用本地代码(如C/C++)实现的。
负责加载Java的核心库,如java.lang.*等。对于Java程序员来说,它是不可见的,无法直接引用它。尝试获取它的实例通常返回null,且没有直接的父加载器。


Extension Class Loader(扩展类加载器):
负责加载Java的扩展库,这些库位于$JAVA_HOME/jre/lib/ext或者由系统属性java.ext.dirs指定的目录中。它是Bootstrap Class Loader的子加载器。


System Class Loader(系统类加载器):
应用程序类加载器(Application Class Loader)。
负责加载用户类路径(classpath)所指定的类库,开发者可以直接使用该类加载器来加载类。
它是Extension Class Loader的子加载器。


类加载器的继承关系
System Class Loader 的父加载器是 Extension Class Loader。
Extension Class Loader 的父加载器是 Bootstrap Class Loader。

ClassLoader 中的两个方法
static ClassLoader getSystemClassLoader():
此方法返回用于委派的系统类加载器(即应用程序类加载器)。

ClassLoader getParent():
此方法返回此类加载器的父类加载器。
Bootstrap Class Loader,此方法通常返回null,因为它没有父加载器(在Java代码中)。
对于其他类型的类加载器(如Extension Class Loader和System Class Loader),此方法将返回其父加载器的实例。

测试代码:

package test.reflect;
public class ClassLoaderDemo {  
    public static void main(String[] args) {  
        // 获取系统类加载器(也称为应用程序类加载器)  
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();  
        System.out.println("系统类加载器(System ClassLoader):" + systemClassLoader.getClass().getName());  
  
        // 尝试获取系统类加载器的父加载器  
        ClassLoader parentClassLoader = systemClassLoader.getParent();  
        if (parentClassLoader != null) {  
            System.out.println("系统类加载器的父加载器:" + parentClassLoader.getClass().getName());  
        } else {  
            System.out.println("系统类加载器的父加载器无法直接访问(可能是Bootstrap ClassLoader)");  
        }  
  
        // 获取Bootstrap ClassLoader的父加载器)将总是返回null  
        // Bootstrap ClassLoader在Java代码中没有直接的父加载器  
        ClassLoader grandparentClassLoader = parentClassLoader != null ? parentClassLoader.getParent() : null;  
        System.out.println("父加载器的父加载器(Bootstrap ClassLoader的父加载器):" + (grandparentClassLoader != null ? grandparentClassLoader.getClass().getName() : "null"));  
    }  
}

运行结果如下:

........................................................................................................................................................ 

2、反射机制:

Java反射(Reflection)机制,允许程序在运行时(runtime)检查或修改类的行为。主要依赖于java.lang.reflect包中的类和接口。通过反射,可以动态地创建类的实例、访问类的私有成员(包括字段、方法)、调用任何方法,甚至是在编译时并不知道的类的方法。

测试代码1:

package test.reflect;
import java.lang.reflect.InvocationTargetException;  
import java.lang.reflect.Method;  
 //使用反射机制调用一个类的私有方法。 
public class ReflectionDemo {  
  
    private void privateMethod() {  
    	
        System.out.println("Private method called.");  
    }  
  
    public static void main(String[] args) {  
        try {  
            // 获取Class对象  
            Class<?> clazz = Class.forName("test.reflect.ReflectionDemo");  
  
            // 创建实例  
            Object instance = clazz.getDeclaredConstructor().newInstance();  
  
            // 获取私有方法  
            Method method = clazz.getDeclaredMethod("privateMethod");  
  
            // 设置为可访问  
            method.setAccessible(true);  
  
            // 调用私有方法  
            method.invoke(instance);  
  
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException |  
                 NoSuchMethodException | InvocationTargetException e) {  
            e.printStackTrace();  
        }  
    }  
}

运行结果如下:

........................................................................................................................................................

测试代码2:

创建一个Flower类:

package test.reflect;
public class Flower {  
    // 私有成员变量  
    private String species;  
      
    // 默认(包级私有)成员变量  
    String color;  
      
    // 公共成员变量  
    public String fragrance;  
      
    // 无参构造方法  
    public  Flower() {  
      
    }  
      
    // 默认构造方法  
    Flower(String color) {  
        this.color = color;  
    }  
      
    // 公共构造方法1  
    public Flower(String species, String color) {  
        this.species = species;  
        this.color = color;  
    }  
      
    // 公共构造方法2  
    public Flower(String species, String color, String fragrance) {  
        this.species = species;  
        this.color = color;  
        this.fragrance = fragrance;  
    }  
      
    public String getSpecies() {
		return species;
	}

	public void setSpecies(String species) {
		this.species = species;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public String getFragrance() {
		return fragrance;
	}

	public void setFragrance(String fragrance) {
		this.fragrance = fragrance;
	}

	// 私有成员方法  
    @SuppressWarnings("unused")
	private void privateMethod() {  
        System.out.println("Private method called.");  
    }  
      
    // 公共成员方法1  
    public void publicMethod1() {  
        System.out.println("Public method 1 called. Flower details: species=" + species + ", color=" + color + ", fragrance=" + fragrance);  
    }  
      
    // 公共成员方法2  
    public void publicMethod2(String newColor) {  
        this.color = newColor;  
        System.out.println("Color changed to: " + newColor);  
    }  
      
    // 重写toString方法  
    @Override  
    public String toString() {  
        return "Flower{" +  
               "species='" + species + '\'' +  
               ", color='" + color + '\'' +  
               ", fragrance='" + fragrance + '\'' +  
               '}';  
    }  
}

使用反射获取构造方法:

package test.reflect;
import java.lang.reflect.Constructor;  

public class ReflectionDemoTest {  
    public static void main(String[] args) {  
        try {  
            // 获取Flower类的Class对象  
            Class<?> flowerClass = Flower.class;  
  
            // 使用无参构造方法创建Flower实例  
            Constructor<?> noArgConstructor = flowerClass.getConstructor(); 
            noArgConstructor.setAccessible(true); 
            Flower flower1 = (Flower) noArgConstructor.newInstance();  
            System.out.println(flower1); 
            
            // 使用带有两个参数的构造方法创建Flower实例  
            Constructor<?> twoArgConstructor = flowerClass.getConstructor(String.class, String.class);  
            Flower flower2 = (Flower) twoArgConstructor.newInstance("Rose", "Red");  
            System.out.println(flower2); 
  
            // 使用带有三个参数的构造方法创建Flower实例  
            Constructor<?> threeArgConstructor = flowerClass.getConstructor(String.class, String.class, String.class);  
            Flower flower3 = (Flower) threeArgConstructor.newInstance("Lily", "White", "Sweet");  
            System.out.println(flower3); 
  
            // 私有构造方法不能直接通过getConstructor获取,通常不推荐反射地访问私有构造方法  
            // 如果确实需要,使用getDeclaredConstructor并调用setAccessible(true)  
  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}

运行结果如下:

使用反射获取成员变量:

package test.reflect;
import java.lang.reflect.Field;  

public class TestReflection {  
    public static void main(String[] args) {  
        try {  
            // 创建Flower对象  
            Flower flower = new Flower();  
  
            // 获取Flower类的Class对象  
            Class<?> flowerClass = flower.getClass();  
  
            // 获取private成员变量species并设置为可访问  
            Field speciesField = flowerClass.getDeclaredField("species");  
            speciesField.setAccessible(true);  
            speciesField.set(flower, "Rose"); // 修改对象属性  
  
            // 获取private成员变量color并设置为可访问  
            Field colorField = flowerClass.getDeclaredField("color");  
            colorField.setAccessible(true);  
            colorField.set(flower, "Red"); // 修改对象属性  
  
            // 获取private成员变量fragrance并设置为可访问  
            Field fragranceField = flowerClass.getDeclaredField("fragrance");  
            // 如果成员变量是public的,则不需要setAccessible(true) 
            fragranceField.setAccessible(true);  
            fragranceField.set(flower, "Sweet"); // 修改对象属性  
  
            // 打印修改后的对象信息  
            System.out.println(flower); 
  
        
  
        } catch (NoSuchFieldException | IllegalAccessException e) {  
            e.printStackTrace();  
        }  
    }  
}

运行结果如下:

使用反射获取成员方法:

package test.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;  

public class ReflectionTest {  
    public static void main(String[] args) {  
        try {  
            // 创建Flower对象  
            Flower flower = new Flower("Rose", "Red");  
  
            // 获取Flower类的Class对象  
            Class<?> flowerClass = flower.getClass();  
  
            // 获取成员方法publicMethod1 
            Method publicMethod1 = flowerClass.getMethod("publicMethod1");  
  
            // 调用publicMethod1  
            publicMethod1.invoke(flower); 
  
            // 如果方法需要参数  
             Method setColorMethod = flowerClass.getMethod("setColor", String.class);  
             setColorMethod.invoke(flower, "Pink"); // 调用setColor方法,将color设置为Pink  
             System.out.println(flower);
  
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {  
            e.printStackTrace();  
        }  
    }  
}

运行结果如下:

使用反射同时获取构造方法、成员变量和成员方法:

package test.reflect;
import java.lang.reflect.Constructor;  
import java.lang.reflect.Field;  
import java.lang.reflect.InvocationTargetException;  
import java.lang.reflect.Method;  
  
public class ReflectionExample {  
    
    public static void main(String[] args) {  
        // 获取Flower类的Class对象  
        Class<Flower> flowerClass = Flower.class;  
  
        // 通过反射创建Flower类的实例  
        try {  
            // 使用带参数的构造方法  
            Constructor<Flower> constructor = flowerClass.getDeclaredConstructor(String.class, String.class, String.class);  
            Flower flowerInstance = constructor.newInstance("Rose", "Red", "Fragrant");  
            System.out.println(flowerInstance);  
  
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {  
            e.printStackTrace();  
        }  
  
        // 访问Flower类的私有成员  
        try {  
            // 访问私有字段  
            Field speciesField = flowerClass.getDeclaredField("species");  
            speciesField.setAccessible(true); // 设置为可访问  
            Flower anotherFlower = new Flower("Tulip", "Purple", "Sweet");  
            Object speciesValue = speciesField.get(anotherFlower);  
            System.out.println(speciesValue); 
            // 调用私有方法  
            Method privateMethod = flowerClass.getDeclaredMethod("privateMethod");  
            privateMethod.setAccessible(true); // 设置为可访问  
            privateMethod.invoke(anotherFlower); 
  
        } catch (NoSuchFieldException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {  
            e.printStackTrace();  
        }  
    }  
}

运行结果如下:

 

  • 23
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值