黑马程序员————反射

------Java培训Android培训iOS培训.Net培训、期待与您交流!-------


一、什么是反射机制

 

简单来说就是程序在运行时能够知道自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。

可以理解为对类的解剖。

 

二.反射的应用场景

 

根据类的名称获取其字节码文件,获取其中的内容并调用

 

三、获取Class类的方法

 

对象.getClass()

类名.class,

Class.forName(“类名”) 


1.Object类中的getClass()方法,可是这种方法比较麻烦,必须创建类。

Person p = new Person();
Class clazz = p.getClass();
Person p1 = new Person();
Class clazz1 = p.getClass();
System.out.println(clazz==clazz1);

2.任何一个数据类型都具备一个静态的属性,class来获取class对象,可是这种方法还是要明确类中的静态成员。

Class clazz = Person.class;
Class clazz1 = Person.class;
System.out.println(clazz==clazz1);

3.根据类名来获取对象(重点)

Class clazz = Class.forName("bean.Person");//注意类名要带包名
System.out.println(clazz);

四、获取Class中的构造函数

 

Constructor类代表某个类中的一个构造方法

1.产生空参对象,并初始化 

通过newInstance() 方法

Class clazz = Class.forName("bean.Person");

Object obj = clazz.newInstance();


2.得到某个类(String类)所有的构造方法:

Constructor[]  constructors  =  Class.forName("java.lang.String").getConstructors();


3.产生指定参数的对象,并初始化

得到String(StringBuilder builder) 构造方法:

Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);


得到指定的实例对象

通常方式:String str = new String(new StringBuffer("abc"));

反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc"));

错误实例: String str = (String)constructor.newInstance("abc");

//调用获得的方法时要用到上面相同类型的实例对象


Class.newInstance()方法

 

例子:

String obj = (String)Class.forName("java.lang.String").newInstance();

 

该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。


该方法内部的具体代码是怎样写的呢?

用到了缓存机制来保存默认构造方法的实例对象。

 

备注:

九个预定义Class实例对象:

基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。 


而判断是否是基本的Class对象用:

Class.isPrimitive方法


Int.class == Integer.TYPE  是true

Integer.TYPE:表示基本类型 int 的 Class 实例。




五、获取Class中的字段

 

Field类代表某个类中的一个成员变量


例子:

public int x;

private  int y;

//1.先获取共有的字段

Field fieldX = ReflectPoint.class.getField("x");

System.out.println("x = "+fieldX.get(point));


//2.获取私有的字段,暴力反射

Field fieldY = ReflectPoint.class.getDeclaredField("y");

fieldY.setAccessible(true);

System.out.println("y = "+fieldY.get(point));

 

练习:将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"。

package cn.itheima;
public class ReflectPoint {
public int x;
private  int y;
public String str1 = "ball";
public String str2 = "basketball";
public String str3 = "itcast";
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public String toString(){
return str1+":"+str2+":"+str3;
}
}
 
 
package cn.itheima;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
ReflectPoint point = new ReflectPoint(3,6);
changeString(point);
System.out.println(point);
}
 
private static void changeString(ReflectPoint point) throws Exception {
Field[] fields = point.getClass().getFields();
for(Field field:fields){
if(field.getType()==String.class){
String oldValue = (String) field.get(point);
String newValue  = oldValue.replace('b', 'a');
field.set(point,newValue);
}
}
}
}
 


六、获取Class中的方法

 

1.获取公共方法和私有的方法

Class clazz = Class.forName("com.itheima.bean.Person");

Method[] methods  = clazz.getMethods();//获取的都是公有的方法。 
methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包含私有。 
for(Method method : methods){
System.out.println(method);
}


2.调用方法:

public class Person {

	private int age;
	private String name;
	
	public Person(String name,int age) {
		super();
		this.age = age;
		this.name = name;
		
		System.out.println("Person param run..."+this.name+":"+this.age);
	
	}
	public Person() {
		super();
		System.out.println("person run");
				
	}
	public void show(){
		System.out.println(name+"...show run..."+age);
	}
	
	private void privateMethod(){
		System.out.println(" method run ");
	}
	
	public void paramMethod(String str,int num){
		System.out.println("paramMethod run....."+str+":"+num);
		
	}
	public static void staticMethod(){
		System.out.println(" static method run......");
	}
}

public class ReflectDemo5 {
	<strong>//反射类的方法:public void show()</strong>
	@Test
	public void test1() throws Exception{
		Person p = new Person();
		Class clazz = Class.forName("bean.Person");
		Method method = clazz.getMethod("show", null);
		method.invoke(p, null);
	}
	
	<strong>//反射类的方法:public void paramMethod(String name,int age)</strong>
	@Test
	public void test2() throws Exception{
		Person p = new Person();
		Class clazz = Class.forName("bean.Person");
		Method method = clazz.getMethod("paramMethod", String.class,int.class);
		method.invoke(p, "小明",20);
	}
	
	<strong>//反射类的方法:private void privateMethod(InputStream in)</strong>
	@Test
	public void test3() throws Exception{
		Person p = new Person();
		Class clazz = Class.forName("bean.Person");
		Method method = clazz.getDeclaredMethod("privateMethod", InputStream.class);
		method.setAccessible(true);//强制访问
		method.invoke(p, new FileInputStream("f:\\test.txt"));
	}
	
	<strong>//反射类的方法:public  Class[] method(String name,int[] password)</strong>
	@Test
	public void test4() throws Exception{
		Person p = new Person();
		Class clazz = Class.forName("bean.Person");
		Method method = clazz.getMethod("method", String.class,int[].class);
		Class cs[] = (Class[]) method.invoke(p, "张三",new int[]{0,1,2});
		System.out.println(cs[0]);
	}
	
	<strong>//反射类的方法:public static void method()</strong>
	@Test
	public void test5() throws Exception{
		Class clazz = Class.forName("bean.Person");
		Method method = clazz.getMethod("method", null);
		method.invoke(null, null);
	}	
}


七、反射的应用

 

多态中主板事例的反射应用

package com.itheima.reflect.test;

public class Mainboard {

	public void run() {
		System.out.println("main board run....");
	}

	public void usePCI(PCI p) {//PCI p = new SouncCard();
		if (p != null) {
			p.open();
			p.close();
		}
	}
}

public class NetCard implements PCI {

	@Override
	public void open() {
		System.out.println("net open");
	}

	@Override
	public void close() {
		System.out.println("net close");
	}

}

public class SoundCard implements PCI {
	public void open(){
		System.out.println("sound open");
	}
	public void close(){
		System.out.println("sound close");
	}

}
public interface PCI {
	
	public void open();
	public void close();

}

import java.io.File;
import java.io.FileInputStream;

import java.util.Properties;


/*
 * 电脑运行。 
 */
public class ReflectTest {

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {

		Mainboard mb = new Mainboard();
		mb.run();
		//每次添加一个设备都需要修改代码传递一个新创建的对象
//		mb.usePCI(new SoundCard());
		//能不能不修改代码就可以完成这个动作。 
//		不用new来完成,而是只获取其class文件。在内部实现创建对象的动作。 
		
		File configFile = new File("pci.properties");
		
		Properties prop = new Properties();
		FileInputStream fis = new FileInputStream(configFile);
		
		prop.load(fis);
		
		for(int x=0; x<prop.size(); x++){
			
			String pciName = prop.getProperty("pci"+(x+1));
			
			Class clazz = Class.forName(pciName);//用Class去加载这个pci子类。 
			
			PCI p = (PCI)clazz.newInstance();
			
			mb.usePCI(p);
		}
		
		fis.close();
		
		
	}

}




------Java培训Android培训iOS培训.Net培训、期待与您交流!-------

 

 

 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
黑马程序员的tb_brand是指在JavaWeb基础教程中创建的一个表。这个表是用来存储品牌信息的,具体的表结构和数据类型需要和JavaBean类中的成员变量保持一致。\[1\]在这个教程中,使用了Maven来构建项目,并且使用了MyBatis作为持久层框架,通过配置pom.xml文件来引入相关依赖。\[2\] Maven是一个用于管理和构建Java项目的工具,它提供了一套标准化的项目结构、构建流程和依赖管理机制。\[3\] #### 引用[.reference_title] - *1* [【JAVAWEB开发】黑马程序员java web案例资料(含Element的删除与修改)](https://blog.csdn.net/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.csdn.net/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.csdn.net/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、付费专栏及课程。

余额充值