java学习-反射机制

1、什么是反射:

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射就是把java类中的各种成分映射成一个个的Java对象。

一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象,(一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)

2、Class类与reflect包

Java反射机制主要是 java.lang.Class类和java.lang.reflect包

2.1、Class类:

Class类是实现反射的关键所在,Class类的一个实例表示Java的一种数据类型,包括类、接 口、枚举、注解(Annotation)、数组、基本数据类型和void,void是“无类型”,主要用于方法返回值 类型声明,表示不需要返回值。Class没有公有的构造方法,Class实例是由JVM在类加载时自动创建的

得到Class类对象的三种方式:

  • 类的class属性
  • getClass()方法
  • 类的完全限定名
public class MainTest {

	public static void main(String[] args) throws Exception {
         //User是一个自己创建的类
		//方式一:通过class输出
		Class c1=User.class;
		//方式二:getClass()方法
		User user=new User();
		Class c2=user.getClass();
		//方式三:通过类的完全限定名(内置路径):包名.类名
		Class c3=Class.forName("three.User");
		System.out.println(c1);
		System.out.println(c2);
		System.out.println(c3);
		//比较特殊的数据类型:
		Class c4 = int.class;
		Class c5 = double.class;
		Class c6 = long.class;
		Class c7 = short.class;
		System.out.println(c4);
		System.out.println(c5);
		System.out.println(c6);
		System.out.println(c7);
	}
}

2.2:reflect包:

java.lang.reflect包提供了反射中用到类,主要的类说明如下:

  • Constructor类:提供类的构造方法信息。
  • Field类:提供类或接口中成员变量信息。
  • Method类:提供类或接口成员方法信息。
  • Array类:提供了动态创建和访问Java数组的方法。
  • Modifier类:提供类和成员访问修饰符信息

常用到的方法与对应类如下:

Constructor类:提供类的构造方法信息,

Field类:提供类或接口中成员变量信息。

Method类:提供类或接口成员方法信息。

Array类:提供了动态创建和访问Java数组的方法。

 

Modifier类:提供类和成员访问修饰符信息

3、获取方法信息

用于实验的类Student:


public class Student {
	private String name ="admin";
	public int age = 18;
	protected String email = "sfss@qq.com";
	
	private Student(String name) {
		super();
		this.name = name;
	}
	public Student(String name, int age, String email) {
		super();
		this.name = name;
		this.age = age;
		this.email = email;
	}
	private Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", email=" + email + "]";
	}

	public Student() {
		super();
	}
	public static void show() {
		System.out.println("大家下午好!");
	}
	protected void sayHi() {
		System.out.println("hello!");
	}
	
	private void hello(String msg) {
		System.out.println("hello!"+msg);
	}
}

3.1获取公有方法的对象:getMethods()

getMethods():可以得到本类和父类中的所有的公有的方法,返回Method类型的素组,

import java.lang.reflect.Method;
public class MainTest {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("three.Student");//得到类对象
		//得到Student类中的公有方法信息
		Method[] methods = c.getMethods();//getMethods():它可以得到Student为中和父类中的所有的公有的方法,非公有的就得不到了
		for (Method method : methods) {
			System.out.println(method);
		}
	}

}

 3.2构造方法:

a、获取构造方法:

getDeclaredConstructors():得到全部的构造器信息

getConstructors():只能得到公有的构造器信息

getDeclaredConstructor(): 获取public修饰的构造函数(单个)

import java.lang.reflect.*;
public class MainTest {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("three.Student");//得到类对象
		Constructor []con= c.getDeclaredConstructors();//全部的构造器信息
        //Constructor []con= c.getConstructors();//只能得到公有的构造器信息
		for (Constructor constr : con) {
			System.out.println(constr);
		}
	}
}

结果

 获取public修饰的构造函数(单个):getDeclaredConstructor()

b、调用私有的构造方法:

import java.lang.reflect.*;
public class MainTest {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("three.Student");//得到类对象
		Constructor cons = c.getDeclaredConstructor(String.class);
		cons.setAccessible (true);// 暴力访问 setAccessible方法是是否可访问
		Object obj = cons.newInstance("西门庆"); // newInstance:创建对象,等价于new Student("西门庆")
		System.out.println(obj);

	}
}

3.3调用指定方法:

a、调用无参的指定方法

import java.lang.reflect.*;
public class MainTest {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("three.Student");//得到类对象
		Method method = c.getDeclaredMethod("show");//指定show方法
		//执行一下该方法
		Object obj = c.getConstructor().newInstance();//实例化一个Student类的实例
		method.invoke(obj);//调用Student的show方法,invoke()就是调用类中的方法

	}
}

b、 调用有参的指定方法:

import java.lang.reflect.*;
public class MainTest {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("three.Student");//得到类对象
		Method method = c.getDeclaredMethod("hello",String.class);
		Object obj = c.getConstructor().newInstance();
		method.setAccessible(true); //暴力访问
		method.invoke(obj,"张三");
	}
}

3.4判断指定方法是公有,还是私有

import java.lang.reflect.*;
public class MainTest {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("three.Student");//得到类对象
		Method method = c.getDeclaredMethod("show");
		int mod = method.getModifiers();
		System.out.println("是私有吗:"+Modifier.isPrivate(mod));
		System.out.println("是公有吗:"+Modifier.isPublic(mod));
	}
}

4、获取属性

4.1:获取全部属性的对象

import java.lang.reflect.*;
public class MainTest {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("three.Student");//得到类对象
		Field [] f=c.getDeclaredFields();
		for(Field field:f) {
			System.out.println(field);
		}
		
	}
}

4.2 获取指定公共属性的对象,或获取指定私有属性的对象

import java.lang.reflect.*;
public class MainTest {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("three.Student");//得到类对象
		Field f=c.getField("age");//获取指定的公共属性
		System.out.println(f);
		Field f1=c.getDeclaredField("name");//获取指定的私有属性
		System.out.println(f1);
		
	}
}

 4.3 修改属性

import java.lang.reflect.*;
public class MainTest {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("three.Student");//得到类对象
		 Constructor con= c.getConstructor();
		 Object obj = con.newInstance();//实力化对象
		 Field field = c.getField("age"); // 获取单个字段
		 field.set(obj, 30);// 设置值
		 System.out.println(obj);
	}
}

5、操作数组

import java.lang.reflect.Array;

public class One {

	public static void main(String[] args) {
		//普遍建立数组的方式:
		int[] nums = new int[3];  //方式1
		int nums2[] = new int[3];  //方式2
		int[] nums3 = new int[]{1,2,3};  //方式3
		int[] nums4 = {2,3,4,5};  //方式4
		//使用反射Array类来实现
		Object arr = Array.newInstance(int.class, 4);	//创建一个长度为4的int类型数组
		
		//增加元素
		Array.setInt(arr, 0, 100);
		Array.setInt(arr, 1, 200);
		Array.setInt(arr, 2, 300);
		Array.setInt(arr, 3, 400);
		//遍历数组中的元素
		for (int i = 0; i < Array.getLength(arr); i++) {
			Object value = Array.get(arr, i);//获得当前元素
			System.out.print(value+",");
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值