Java 反射

目录

1.定义

2.作用

3.反射常用API

4.利用反射获取Class类型对象的三种方式

4.1准备类

4.2 第一种方式:

4.3 第二种方式:

4.4 第三种方式:

4.5 获取java自带类的类型的三种方式

4.5.1 Class cl1 = Class.forName("java.util.Date");

4.5.2 Class cl2 = Date.class;

4.5.3 Date date = new Date(); Class cl3 = date.getClass();

5.利用反射创建类的对象(调用无参构造)

6.利用反射创建类的对象的意义

7.应用场景:可变长参数

7.1场景一

7.2场景二(如果有可以精确匹配的方法,则调用该方法,不再去执行可变长参数的对应方法)

7.3 场景三(可变长参数可以等同看作数组)

7.4场景四(引入反射机制)

7.5场景五(可变长参数的位置,并且只能出现在所有参数的最后一位)

8.应用场景二:Properties+IO

9.应用场景三:Properties+IO+反射(耦合度降低)


1.定义

Java反射说的是在运行状态中,对于任何一个类,我们都能知道这个类有那些属性和方法。

对于任何一个对象,我们都能对它的方法和属性进行调用。

我们把这种动态获取对象信息和调用对象方法的功能称为反射机制。

2.作用

2.1 反编译 .class--->.java

2.2 通过反射机制访问Java对象的属性,方法,构造方法等。

3.反射常用API

3.1.java.lang.Class

3.2.java.lang.reflect.Constructor

3.3.java.lang.reflect.Filed

3.4.java.lang.reflect.Method

3.5.java.lang.reflect.Modifer

4.利用反射获取Class类型对象的三种方式

4.1准备类

public class Demo1_Employee {
	private String name;

	public Demo1_Employee() {
		System.out.println("无参构造");
	}

	public Demo1_Employee(String name) {
		super();
		this.name = name;
	}

	public void print() {
		System.out.println("我的名字是:" + name);
	}
}

4.2 第一种方式:

Class c1 = Class.forName("cn.kgc.test.Demo1_Employee");

System.out.println(c1);

4.3 第二种方式:

Class c2 = Demo1_Employee.class;

System.out.println(c2);

4.4 第三种方式:

Demo1_Employee demo1_Employee = new Demo1_Employee();

Class c3 = demo1_Employee.getClass();

System.out.println(c3);

三种方式创建的Class类型对象地址相同

4.5 获取java自带类的类型的三种方式

4.5.1 Class cl1 = Class.forName("java.util.Date");

4.5.2 Class cl2 = Date.class;

4.5.3 Date date = new Date(); Class cl3 = date.getClass();

5.利用反射创建类的对象(调用无参构造)

String s = "cn.kgc.test.Demo1_Employee";
//String s = "java.util.Integer";
Class c = Class.forName(s);
Object o = c.newInstance();
System.out.println("输出:***" + o + "***");

利用反射创建类的对象,使用newInstance方法,此时会默认调用类的无参构造,没有就会报错

自己构建的Demo1_Employee类中有无参构造,所以显示了输出语句,Integer类没有无参构造,会报错;Date类中有无参构造,输出了时间

String类型有无参构造,但是输出为空字符串,所以无显示。

6.利用反射创建类的对象的意义

//硬代码,此时创建类的时候需要每次重写

Demo1_Employee demo1_Employee = new Demo1_Employee();

System.out.println(demo1_Employee);

User user = new User();

System.out.println(user);

// 耦合性低---> 代码量少,重复利用率高,此时创建不同的类可以直接修改String s的内容,后期可以通过配置文件来操作s,降低了代码量

String s = "cn.kgc.test.Demo1_Employee";

Class c = Class.forName(s);

Object o = c.newInstance();

System.out.println("输出:***" + o + "***");

7.应用场景:可变长参数

7.1场景一

public class Demo3 {
	public static void print1(int... a) {
		System.out.println("调用方法" + a);
	}

	public static void main(String[] args) {
		print1();
		print1(1);
		print1(1, 2, 33);
	}
}

调用方法,输出a时候,会以数组的形式输出,为地址,结果:

调用方法[I@7852e922

调用方法[I@4e25154f

调用方法[I@70dea4e

7.2场景二(如果有可以精确匹配的方法,则调用该方法,不再去执行可变长参数的对应方法)

public class Demo3 {
	public static void print1(int... a) {
		System.out.println("调用方法" + a);
	}

	public static void print1(int a) {
		System.out.println(a);
	}

	public static void main(String[] args) {
		print1();
		print1(1);
		print1(1, 2, 33);
	}
}

结果:

调用方法[I@7852e922

1

调用方法[I@4e25154f

7.3 场景三(可变长参数可以等同看作数组)

public class Demo3 {
	public static void print2(String... a) {
		for (int i = 0; i < a.length; i++) {
			System.out.print(a[i] + "");
		}
	}

	public static void main(String[] args) {
		print2();
		print2("刘亦菲", "迪丽热巴", "古力娜扎", "李沁", "杨幂");
		String[] a = { "刘亦菲", "迪丽热巴", "古力娜扎", "李沁", "杨幂" };
        System.out.println();

		print2(a);
	}
}

结果:

刘亦菲 迪丽热巴 古力娜扎 李沁 杨幂

刘亦菲 迪丽热巴 古力娜扎 李沁 杨幂

7.4场景四(引入反射机制)

import java.util.Date;

public class Demo3 {
	public static void print3(Class... a) throws Exception, IllegalAccessException {
		for (int i = 0; i < a.length; i++) {
			Class c = a[i];
			System.out.println(c.newInstance());
		}
	}

	public static void main(String[] args) throws IllegalAccessException, Exception {
		print3(Demo1_Employee.class, Date.class);
	}
}

结果:

无参构造

cn.kgc.test.Demo1_Employee@70dea4e

Thu Sep 02 12:14:07 CST 2021

7.5场景五(可变长参数的位置,并且只能出现在所有参数的最后一位)

public static void print4(String... a, int i) {} 编译报错

public static void print4(int i, String... a) {}

8.应用场景二:Properties+IO

创建配置文件,db.properties

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

//利用java读取配置文件db.propertis的数据,先创建配置文件
public class Demo_propertis {
	public static void main(String[] args) throws IOException {
		// 1.实例化Propertis对象
		Properties properties = new Properties();
		// 2.实例化IO对象(输入流对象)
		FileInputStream fileInputStream = new FileInputStream("src\\db.properties");
		// 3.将fileInputStream流对象的数据加载到属性对象中去
		properties.load(fileInputStream);
		// 4.关闭流对象
		fileInputStream.close();
		// 5.获取文件中的值
		String username = properties.getProperty("username");
		// 6.输出
		System.out.println(username);
	}
}

9.应用场景三:Properties+IO+反射(耦合度降低)

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

//利用java读取配置文件db.propertis的数据
public class Demo_propertis2 {
	public static void main(String[] args)
			throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
		// 1.实例化Propertis对象
		Properties properties = new Properties();
		// 2.实例化IO对象(输入流对象)
		FileInputStream fileInputStream = new FileInputStream("src\\db.properties");
		// 3.将fileInputStream流对象的数据加载到属性对象中去
		properties.load(fileInputStream);
		// 4.关闭流对象
		fileInputStream.close();
		// 5.获取文件中的值
		String className = properties.getProperty("className");
		Class c = Class.forName(className);
		Object o = c.newInstance();
		// 6.输出
		System.out.println(o);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值