黑马程序员——高新技术——反射笔记

本文详细阐述了反射技术在Java中的作用与优势,包括如何获取类的组成部分、实例化对象、访问属性和调用方法。通过具体示例展示了反射技术在不同场景下的应用,强调了其强大的扩展性和灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------


反射技术:其实就是动态加载一个指定的类,并获取该类中的所有的内容。而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员。简单说:反射技术可以对一个类进行解剖。

 

反射的好处:大大的增强了程序的扩展性。

 

反射的用法

1)、需要获得java类的各个组成部分,首先需要获得类的Class对象,获得Class对象的三种方式:

       Class.forName(classname)   用于做类加载

       obj.getClass()                       用于获得对象的类型

       类名.class                         用于获得指定的类型,传参用

 

2)、反射类的构造函数:

       Constructorcon = clazz.getConstructor(new Class[]{paramClazz1, paramClazz2,...})

       con.newInstance(params...)

 

3)、反射类的成员方法:

       Classclazz = Person.class;

       Methodmethod = clazz.getMethod(methodName, new Class[]{paramClazz1, paramClazz2});

       method.invoke();

 

4)、反射类的属性:

       Fieldfield = clazz.getField(fieldName);

       field.setAccessible(true);

       field.setObject(value);

 

反射的基本步骤:

1、获得Class对象,就是获取到指定的名称的字节码文件对象。

2、实例化对象,获得类的属性、方法或构造函数。

3、访问属性、调用方法、调用构造函数创建对象。

 

 

获取这个Class对象,有三种方式:

1:通过每个对象都具备的方法getClass来获取。弊端:必须要创建该类对象,才可以调用getClass方法。

2:每一个数据类型(基本数据类型和引用数据类型)都有一个静态的属性class。弊端:必须要先明确该类。

     前两种方式不利于程序的扩展,因为都需要在程序使用具体的类来完成。

3:使用的Class类中的方法,静态的forName方法

     指定什么类名,就获取什么类字节码文件对象,这种方式的扩展性最强,只要将类名的字符串传入即可。

// 1. 根据给定的类名来获得  用于类加载

String classname = "cn.itcast.reflect.Person";//来自配置文件

Class clazz = Class.forName(classname);// 此对象代表Person.class

// 2.如果拿到了对象,不知道是什么类型   用于获得对象的类型

Object obj = new Person();

Class clazz1 = obj.getClass();// 获得对象具体的类型

// 3.如果是明确地获得某个类的Class对象  主要用于传参

Class clazz2 = Person.class

 

获取了字节码文件对象后,最终都需要创建指定类的对象:

 

创建对象的两种方式(其实就是对象在进行实例化时的初始化方式):

1,调用空参数的构造函数:使用了Class类中的newInstance()方法。

2,调用带参数的构造函数:先要获取指定参数列表的构造函数对象,然后通过该构造函数的对象的newInstance(实际参数) 进行对象的初始化。

一般情况下,被反射的类,内部通常都会提供一个公有的空参数的构造函数。

 

//获取一个带参数的构造器。

      

  Constructorconstructor = clazz.getConstructor(String.class,int.class);
        //想要对对象进行初始化,使用构造器的方法newInstance();
        Object obj =constructor.newInstance("zhagnsan",30);
        //获取所有构造器。
        Constructor[] constructors =clazz.getConstructors();//只包含公共的
        constructors= clazz.getDeclaredConstructors();//包含私有的
        for(Constructorcon : constructors) {
            System.out.println(con);
        }
    }

练习:

import java.lang.reflect.Constructor;
import java.lang.reflect.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class test1 {

	public static void main(String[] args) throws Exception {
		mether1();
		mether2();
		mether3();
		mether4();
	}
	
	//获取字节码class
		public static void mether1() throws Exception{
			// 1. 根据给定的类名来获得  用于类加载
			String classname = "javaenhance.Person";// 一般来自配置文件
			Class c1 = Class.forName(classname);// 此对象代表Person.class

			// 2. 如果拿到了对象,不知道是什么类型   用于获得对象的类型
			Object obj = new Person();
			Class c2 = obj.getClass();// 获得对象具体的类型
					
			// 3. 如果是明确地获得某个类的Class对象  主要用于传参
			Class c3 = Person.class;	
					
			System.out.println(c1);
			System.out.println(c2);
			System.out.println(c3);	
			System.out.println("获取获取字节码class");
			System.out.println();
		}

	//实例化对象
	private static void mether2() throws Exception {
		Class c = Person.class;
		Constructor co = c.getDeclaredConstructor();
		Person p = (Person) co.newInstance();
		
		Constructor co1 = c.getDeclaredConstructor(String.class,int.class);
		Person p1 = (Person) co1.newInstance("sharry",11);
		
		System.out.println(p.toString());
		System.out.println(p1.toString());
		
		System.out.println("实例化对象");
		System.out.println();
	}
	
	//调用成员方法
		private static void mether3() throws Exception{
			// TODO 自动生成的方法存根
			Class c = Person.class;
			Constructor co1 = c.getDeclaredConstructor(String.class,int.class);
			Person p1 = (Person) co1.newInstance("sharry",11);
			
			System.out.println(p1.toString());
			
			Method method = c.getMethod("setName", String.class);
			method.invoke(p1, "make");
			
			System.out.println(p1.toString());
			
			System.out.println("调用成员方法");
			System.out.println();
		}
		
		//获取属性
		private static void mether4(){
			Class<?> demo = null;
	        try {
	            demo = Person.class;
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	        // 取得本类的全部属性
	        Field[] field = demo.getDeclaredFields();
	        for (int i = 0; i < field.length; i++) {
	            // 权限修饰符
	            int mo = field[i].getModifiers();
	            String priv = Modifier.toString(mo);
	            // 属性类型
	            Class<?> type = field[i].getType();
	            System.out.println(priv + " " + type.getName() + " "
	                    + field[i].getName() + ";");
	        }
	        System.out.println("获取属性");
			System.out.println();
		}
}


class Person {
	
	private String name;
	private int age;
	
	public Person() {
	}

	public Person(String name, int age) {
		
		this.name = name;
		this.age = age;
	}
	
	public String toString(){
		return "name:"+name+" age:"+age;
	}
	
	public String sayHello(int age,String name){
		return "My name is "+name+","+age+"years old ,nice to meet you ";
	}
	
	private void myPrivate(){
		System.out.println("i am private");
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

运行结果

class javaenhance.Person
class javaenhance.Person
class javaenhance.Person
获取获取字节码class


name:null age:0
name:sharry age:11
实例化对象


name:sharry age:11
name:make age:11
调用成员方法


private java.lang.String name;
private int age;
获取属性



黑马程序员的tb_brand是指在JavaWeb基础教程中创建的一个表。这个表是用来存储品牌信息的,具体的表结构和数据型需要和JavaBean中的成员变量保持一致。\[1\]在这个教程中,使用了Maven来构建项目,并且使用了MyBatis作为持久层框架,通过配置pom.xml文件来引入相关依赖。\[2\] Maven是一个用于管理和构建Java项目的工具,它提供了一套标准化的项目结构、构建流程和依赖管理机制。\[3\] #### 引用[.reference_title] - *1* [【JAVAWEB开发】黑马程序员java web案例资料(含Element的删除与修改)](https://blog.youkuaiyun.com/aasd23/article/details/126940147)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [黑马程序员-MyBatis 框架-最全入门笔记、阿伟看了都得说真大、真细、真全!!!](https://blog.youkuaiyun.com/qq_57383364/article/details/128103058)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [JavaWeb——黑马程序员课程笔记](https://blog.youkuaiyun.com/King_ZACC/article/details/128573804)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值