今天分享一些反射的小知识
反射是一种发生在程序运行期的行为
public class ReflectDemo01 {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException {
Properties pro=new Properties();
pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
//通过反射方式创建对象
Person p=(Person) Class.forName(pro.getProperty("name")).newInstance();
p.test();
class Person{
public void test(){
System.out.println("我是person");
}
}
class Student extends Person{
public void test(){
System.out.println("我是student");
}
}
class Teacher extends Person{
public void test(){
System.out.println("我是Teacher");
}
}
Java 反射机制,可以实现以下功能:
①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理
1.在创建类型的对象的时候,获取的是类型的Class对象的一个镜像|复制体
2.在一个类加载到内存时就会存在这个类型唯一的Class对象(方法,属性,构造器…)
3.如果能够拿到一个类型的Class对象,就可以操作这个类
获取一个类型的Class对象的方式:
1.类名.class
2.对象.getClass()
3.Class.forName(报名+类名|权限定名)
public class ReflectDemo02{
public static void main(String[] args) throws ClassNotFoundException {
//1.类名.class
Class<String> cls1=String.class;
System.out.println(cls1);
//2.对象.getClass()
Class cls2="你好".getClass();
System.out.println(cls1==cls2); //true
//3.Class.forName(报名+类名|权限定名)
Class cls3=Class.forName("java.lang.String");
System.out.println(cls1==cls3); //true
//4.通过子类的Class对象获取父类的Class对象
Class cls4=cls1.getSuperclass();
System.out.println(cls4);
//基本数据类型的Class对象
Class clsInt=int.class;
System.out.println(clsInt); //int
Class clsInteger=Integer.class;
System.out.println(clsInteger); //class java.lang.Integer
System.out.println(clsInt==clsInteger);//false
//Integer.TYPE-->int的Class类型的对象
System.out.println(int.class==Integer.TYPE);
//常用方法
//Class<?>[] getInterfaces() 当前Class对象所表示的类|接口所实现的接口的Class对象数组
Class<?>[] arr=cls1.getInterfaces();
System.out.println(Arrays.toString(arr));
//int getModifiers() 返回此类或接口以整数编码的 Java 语言修饰符。
System.out.println("类的修饰符的和"+Modifier.toString(cls1.getModifiers()));
// String getName() 报名+类名
System.out.println(cls1.getName());
//String getSimpleName() 类名
System.out.println(cls1.getSimpleName());
//boolean isPrimitive() 判定指定的 Class 对象是否表示一个基本类型。
System.out.println(Integer.TYPE.isPrimitive());
}
}
Class中的常用方法(操作构造器,操作方法,操作字段…)
public static void testMethod(Class cls) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchMethodException, SecurityException{
Method[] methods= cls.getDeclaredMethods();
System.out.println(Arrays.toString(methods));
//创建User类型的对象
User user=(User) cls.getConstructor(String.class,int.class,double.class).newInstance("王五",28,100);
//调用User类中的某个方法 str是方法返回值
String str=(String) methods[0].invoke(user);
System.out.println(str);
Method method=cls.getDeclaredMethod("hehe");
//私有方法方法权限
method.setAccessible(true);
//静态方法调用,第一个参数 (对象|null)
// method.invoke(obj);
method.invoke(null);
method.setAccessible(false);
}
通过反射获取类中构造器:
Constructor<T> getConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
Constructor<?>[] getConstructors()
返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
Constructor<?>[] getDeclaredConstructors()
返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
通过反射创建对象:
1.Constructor->newInstance(参数的class对象...)
2.Class类中newInstance()
*/
public static void testConstructor(Class cls) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
Constructor[] cons=cls.getConstructors();
System.out.println(Arrays.toString(cons));
//1.Constructor->newInstance(Class...)
User user=(User) cons[1].newInstance("zhangsan");
System.out.println(user);
System.out.println(cons[0].getName());
//不能通过私有的构造器创建对象,setAccessible(boolean)设置权限,true->放开权限 false->关闭权限
Constructor con=cls.getDeclaredConstructor(String.class,int.class);
con.setAccessible(true);
User user2=(User) con.newInstance("lisi",30);
System.out.println(user2);
con.setAccessible(false);
//2.Class->newInstance()
Object obj=cls.newInstance(); //默认调用空构造
System.out.println(obj);
}
}
class User{
public String name;
int age;
private double money;
public User() {
// TODO Auto-generated constructor stub
}
public User(String name) {
this.name = name;
}
private User(String name,int age) {
this.name = name;
this.age=age;
}
User(String name, double money) {
this.name = name;
this.money = money;
}
public User(String name, int age, double money) {
super();
this.name = name;
this.age = age;
this.money = money;
}
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;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public void haha(){
System.out.println("hahahhaa...");
}
private static void hehe(){
System.out.println("hehhehhe...");
}
void xixi(){
System.out.println("xixixixi...");
}
@Override
public String toString() {
System.out.println("toString()方法执行啦");
return "User [name=" + name + ", age=" + age + ", money=" + money + "]";
}
}