Java基础之反射

反射

想必大家都听过一句话,框架=注解+反射+设计模式,由此可见反射的重要性。

什么是反射?

我的理解是:

Java应用程序运行的步骤是:①由javac.exe将.java文件编译成.class文件 ②由java.exe将.class字节码文件解释运行。反射就是通过内存中的.class文件对象获取该类的内部结构,并且可以创建该类的实例,调用此对象的属性和方法。

怎么使用反射?就需要使用到Java.lang.Class类

Class类的对象可以是:①类②接口③枚举④数组⑤注解⑥基本数据类型⑦void

@Test
	public void test5() {
		// Class类的对象可以是:①类②接口③枚举④注解⑤数组⑥基本数据类型⑦void
		Class c1=Student.class;
		Class c2=Serializable.class;
		Class c3=ElementType.class;
		Class c4=int [].class;
		Class c5=String [][].class;
		Class c6=Override.class;
		Class c7=int.class;
		Class c8=void.class;
		// 只要数据类型一致并且都是相同维度,则对应的Class对象也一样
	   int [] arr=new int [10];
	   int [] arr1=new int [10];
	   Class c9=arr.getClass();
	   Class c10=arr1.getClass();
	   System.out.println(c9==c10);
	   String [][] str=new String [10][];
	   String [][] str1=new String [11][];
	   Class c11=str.getClass();
	   Class c12=str1.getClass();
	   System.out.println(c11==c12);
	}

Class类获取实例是运行时行为,动态性的

@Test
	public void test7() throws Exception {
		// 类加载是个运行时行为,动态的
		int num=new Random().nextInt(3); // 0 1 2
		switch(num) {
		case 0:
			String str=(String) getInstance("java.lang.String");
			System.out.println(str.toString());
			break;
		case 1:
			Date date=(Date)getInstance("java.util.Date");
			System.out.println(date.toString());
			break;
		case 2:
			Student s=(Student)getInstance("reflect.Student");
			System.out.println(s.toString());
			break;
		}
	}
	public Object getInstance(String clathPath) throws Exception {
		Class clazz=Class.forName(clathPath);
		return clazz.getConstructor(null).newInstance(null);
	}

1.Class类的实例化的三种方式:①类名.class ②对象.getClass() ③Class.forName("全限定类名") :最常用 ④使用类加载器

由于.class文件在内存中的对象就存在一份,所以三种方式实例化的对象都指向相同地址。

//Student类对应的Class类对象,在内存中只有一份。 当我们new Student()去创建一个实例时,jvm就会在磁盘中查找Student.class文件,并将其加载到内存中,一个类对应一个Class对象
		//Class对象的实例化的三种方式
		// 1.类名.class
		Class clazz = Student.class;
		System.out.println(clazz);
		// 2.对象.getClass()
		Class clazz1=new Student().getClass();
		System.out.println(clazz1);
		System.out.println(clazz==clazz1);
		// 3.Class.forName("全限定类名") :这种方式最常用
		Class clazz2=Class.forName("reflect.Student");
		System.out.println(clazz2);
		System.out.println(clazz==clazz2);
		// 4.使用类加载器
		ClassLoader loader=ReflectionTest.class.getClassLoader();
		Class clazz3=loader.loadClass("reflect.Student");
		System.out.println(clazz3);
		System.out.println(clazz==clazz3);

2.获取当前运行时类的构造器

package reflect;

import java.io.Serializable;
import java.util.Comparator;


public class Student {
	public int id;
	protected String name;
	String major;
	private char sex;
	
	public Student() {
		super();
		System.out.println("public Student()");
	}
	
	

	protected Student(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	 

	 Student(int id, String name, String major) {
		super();
		this.id = id;
		this.name = name;
		this.major = major;
	}

	 private  Student( String name) {
			super();
			this.name = name;
		}

	public Student(int id, String name, String major, char sex) {
		super();
		this.id = id;
		this.name = name;
		this.major = major;
		this.sex = sex;
	}
	

	@Override
	public java.lang.String toString() {
		return "Student [id=" + id + ", name=" + name + ", major=" + major + ", sex=" + sex + "]";
	}
}

getConstructors():获取当前运行时类的所有public权限的构造器

getDeclaredConstructors():获取当前运行时类的所有权限的构造器 

@Test
	public void test2() throws Exception {
		// 通过反射获取构造器
		Class clazz=Class.forName("reflect.Student");
		//getConstructors():获取当前运行时类中的public构造器
		Constructor [] cons=clazz.getConstructors();
		for(Constructor c:cons) {
			System.out.print(c+"\t");
		}
		System.out.println();
		//getDeclaredConstructors():获取当前运行时类的所有权限的构造器
		Constructor [] cons1=clazz.getDeclaredConstructors();
		for(Constructor c:cons1) {
			System.out.print(c+"\t");
		}
		System.out.println();
		//通过反射获取当前运行时类的实例
		// 1.调用newInstance():调用当前运行时类的无参构造器
		clazz.getConstructor().newInstance();
		// 2.通过调用getDeclaredConstructor():获取所有权限的构造器
		Constructor c=clazz.getDeclaredConstructor(int.class,java.lang.String.class,java.lang.String.class,char.class);
		Student s=(Student)c.newInstance(1001,"小明","英语",'男');
		System.out.println(s.toString());
		// 获取私有属性的构造器
		Constructor c1=clazz.getDeclaredConstructor(java.lang.String.class);
		c1.setAccessible(true);
		Student s1=(Student)c1.newInstance("小付");
		System.out.println(s1);
	}

3. 获取当前运行时类的属性

getFields():获取当前运行时类以及父类的所有public属性

getDeclaredFields():获取当前运行时类的所有权限的属性

public class Person<T> {
	public int age;
	protected String NickName;
	double height;
	private double weight;
	
    public void  info() {
    	System.out.println("我是一个人");
    }
}
public class Student  extends Person{
	public int id;
	protected String name;
	String major;
	private char sex;
	
	public Student() {
		super();
		System.out.println("public Student()");
	}
	
	

	protected Student(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	 

	 Student(int id, String name, String major) {
		super();
		this.id = id;
		this.name = name;
		this.major = major;
	}

	 private  Student( String name) {
			super();
			this.name = name;
		}

	public Student(int id, String name, String major, char sex) {
		super();
		this.id = id;
		this.name = name;
		this.major = major;
		this.sex = sex;
	}
	

	@Override
	public java.lang.String toString() {
		return "Student [id=" + id + ", name=" + name + ", major=" + major + ", sex=" + sex + "]";
	}
}
@Test
	public void test3() throws Exception {
		Class clazz=Class.forName("reflect.Student");
		//getFields():获取当前运行时类以及父类的所有public属性
		Field [] fields=clazz.getFields();
		for(Field f:fields) {
			System.out.print(f+"\t");
		}
		System.out.println();
		//getDeclaredFields():获取当前运行时类的所有权限的属性
		Field [] fs=clazz.getDeclaredFields();
		for(Field f:fs) {
			System.out.print(f+"\t");
		}
		System.out.println();
		//调用getDeclaredField(参数1):参数1为属性名,获取属性
		//为某个对象属性赋值:set(obj,value)
		Student s=(Student)clazz.getConstructor().newInstance();
		Field field=clazz.getDeclaredField("name");
		field.set(s, "小明");
		System.out.println(s.toString());
	}

 4.获取当前运行时类的非静态方法

getDeclaredMethod(参数1,参数2):获取当前运行时类的方法

参数1:方法名   参数2:方法参数

private void info(String name) {
		System.out.println("我是一名叫做"+name+"的学生");
	}
@Test
	public void test4() throws Exception {
		Class clazz=Class.forName("reflect.Student");
		//getMethods():获取当前运行时类以及父类的public方法
		Method [] ms=clazz.getMethods();
		for(Method method:ms) {
			System.out.println(method);
		}
		System.out.println("**********************");
		//getDeclaredMethods():获取当前运行时类的所有权限的方法
		Method [] mes=clazz.getDeclaredMethods();
		for(Method method:mes) {
			System.out.println(method);
		}
		System.out.println("************************");
		//getDeclaredMethod(参数1,参数2):参数1为方法名,参数2为方法的参数
		Method method=clazz.getDeclaredMethod("info",String.class);
		method.setAccessible(true);
		method.invoke(clazz.getConstructor().newInstance(null), "小明");
	}

 Properties使用的两种方式:

@Test
	public void test6() throws IOException {
		//方法1:默认的路径是当前项目下的路径
		Properties properties=new Properties();
//		FileInputStream fis=new FileInputStream("jdbc.properties");
//		properties.load(fis);
//		System.out.println("username = "+properties.getProperty("uerName")+" password = "+properties.getProperty("passWord"));
		//方法2:默认的路径是当前项目下的src下的路径
		ClassLoader loader=ReflectionTest.class.getClassLoader();
		InputStream is=loader.getResourceAsStream("jdbc.properties");
		properties.load(is);
		System.out.println("username = "+properties.getProperty("uerName")+" password = "+properties.getProperty("passWord"));
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值