目录
方式三: 调用Class的静态方法:forName(String classPath)
对于反射的理解
Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
框架 = 反射 + 注解 + 设计模式。
反射机制能提供的功能
反射前后的操作对比
首先是Person类
public class Person {
private String name;
public int age;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
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 Person(String name, int age) {
this.name = name;
this.age = age;
}
private Person(String name) {//权限为private私有
this.name = name;
}
public Person() {
System.out.println("Person()");
}
public void show(){
System.out.println("你好,我是一个人");
}
private String showNation(String nation){
System.out.println("我的国籍是:" + nation);
return nation;
}
}
反射之前,对于Person类的操作
public void test1() {
//1.创建Person类的对象
Person p1 = new Person("Tom", 12);
//2.通过对象,调用其内部的属性、方法
p1.age = 10;
System.out.println(p1.toString());
p1.show();
//在Person类外部,不可以通过Person类的对象调用其内部私有结构。
//比如:name、showNation()以及私有的构造器
}
Person{name=’Tom’, age=10}
你好,我是一个人
反射之后,对于Person类的操作
public void test2() throws Exception{
Class clazz = Person.class;
//1.通过反射,创建Person类的对象
Constructor cons = clazz.getConstructor(String.class,int.class);
Object obj = cons.newInstance("Tom", 12);
Person p = (Person) obj;
System.out.println(p.toString());
//2.通过反射,调用对象指定的属性、方法
//调用属性
Field age = clazz.getDeclaredField("age");
age.set(p,10);
System.out.println(p.toString());
//调用方法
Method show = clazz.getDeclaredMethod("show");
show.invoke(p);
System.out.println("*******************************");
//通过反射,可以调用Person类的私有结构的。比如:私有的构造器、方法、属性
//调用私有的构造器
Constructor cons1 = clazz.getDeclaredConstructor(String.class);
cons1.setAccessible(true);
Person p1 = (Person) cons1.newInstance("Jerry");
System.out.println(p1);
//调用私有的属性
Field name = clazz.getDeclaredField("name");
name.setAccessible(true);
name.set(p1,"HanMeimei");
System.out.println(p1);
//调用私有的方法
Method showNation = clazz.getDeclaredMethod("showNation", String.class);
showNation.setAccessible(true);
String nation = (String) showNation.invoke(p1,"中国");//相当于String nation = p1.showNation("中国")
System.out.println(nation);
}
Person{name=’Tom’, age=12}
Person{name=’Tom’, age=10}
你好,我是一个人
*******************************
Person{name=’Jerry’, age=0}
Person{name=’HanMeimei’, age=0}
我的国籍是:中国
中国
反射可能出现的问题:
1.通过new的方式或反射的方式都可以调用公共的结构,开发中到底用哪个?
直接用new的方式。
2.什么时候会用反射的方式?(反射的主要特征是动态性)
3.反射机制与面向对象中的封装性并不矛盾。
关于java.lang.Class类的理解
1.类的加载过程:程序经过javac.exe命令之后,会生成一个或多个字节码文件(.class结尾)。之后我们使用java.exe命令对某个字节码文件进行解释运行,相当于将某个字节码文件加载到内存中。加载到内存中的类,我们将其称为运行时类(Class的一个实例)。
2.加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式来获取运行时类。
获取Class的实例的方式
方式一:调用运行时类的属性(泛型):.class
Class<Person> clazz1 = Person.class;//泛型
System.out.println(clazz1);
class com.atguigu.java.Person
方式二:通过运行时类的对象,调用getClass()
Person p1 = new Person();
Class clazz2 = p1.getClass();//获取一下对象是哪个类造的
System.out.println(clazz2);
Person()
class com.atguigu.java.Person
方式三: 调用Class的静态方法:forName(String classPath)
Class clazz3 = Class.forName("com.atguigu.java.Person");//去寻找这个路径下的这个类,运行之后可以判断是否正确
// clazz3 = Class.forName("java.lang.String");
System.out.println(clazz3);//class com.atguigu.java.Person
方式四:使用类的加载器:ClassLoader (了解)
ClassLoader classLoader = ReflectionTest.class.getClassLoader();//加载到内存中的类,运行时类
Class clazz4 = classLoader.loadClass("com.atguigu.java.Person");
System.out.println(clazz4);//class com.atguigu.java.Person
Class实例是哪些结构的说明;
int[] a = new int[10];
int[] b = new int[100];
Class c10 = a.getClass();
Class c11 = b.getClass();
// 只要数组的元素类型与维度一样,就是同一个Class
//一维数组,整数类型的元素
System.out.println(c10 == c11);//true
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/83283.html