• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Y-wee
博客园    首页    新随笔    联系   管理     

Java 反射

Java 反射

1、类的生命周期

参考资料:https://www.cnblogs.com/jhxxb/p/10900405.html

2、类加载器

2.1、类加载器的分类

  • 启动类加载器

  • 扩展类加载器

  • 系统类加载器

参考资料:https://blog.csdn.net/m0_38075425/article/details/81627349

public static void main(String[] args) { 
   System.out.println("person类是哪种类型的类加载器加载="+Person.class.getClassLoader());
  //获取启动类加载器的加载路径
   URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();
   //遍历路径数组并输出
   for(URL url:urls) {
       System.out.println(url.toExternalForm());
  }
   System.out.println("获取扩展类加载器加载的路径");
   //获取扩展类加载器
   ClassLoader extClassLoader=Student.class.getClassLoader().getParent();
   //获取扩展类加载器加载的路径
   URL[] urls2= ((URLClassLoader)extClassLoader).getURLs();
   //遍历路径数组并输出
   for(URL url:urls2) {
       System.out.println(url.toExternalForm());
  }
   System.out.println("获取用户系统的类加载器加载的路径");
   //获取系统类加载器路径
   URL urls3[]= ((URLClassLoader)Student.class.getClassLoader()).getURLs();
   //遍历路径数组并输出
   for(URL url:urls3) {
       System.out.println(url.toExternalForm());
  }
}

3、反射机制

它允许运行中的Java程序获取自身的信息,并且可以操作类或对象的内部属性。

3.1、反射机制起作用的原因

通过类加载器将类加载到内存,它就会生成一个Class类对象 ,此对象可以访问类的静态存储结 构,因此就可以使到在运行期间(runtime) ,可以动态操作类或者对象内部属性及方法。

3.2、获取Class对象

下面代码展示的前提是有一个People类

package reflect;
​
public class People {
   public String name;//姓名
   private int age;//年龄
   public static double height;//身高
​
   public People() {
  }
​
   public People(String name, int age) {
       this.name = name;
       this.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 void show(){
       System.out.println("hello");
  }
   
   public void show(String s){
       System.out.println(s);
  }
   
   private void show(int i){
       System.out.println(i);
  }
   
   @Override
   public String toString() {
       return "People{" +
               "name='" + name + '\'' +
               ", age=" + age +
               '}';
  }
}
​

获取Class对象通常有三种方式

  • Object ——> getClass();

  • 任何数据类型(包括基本数据类型)都有一个“静态”的class属性

  • 通过Class类的静态方法:forName(String className)(常用)

public static void main(String[] args) throws ClassNotFoundException {
       People people=new People();
       //获取Class方式一
       Class peopleClass1=people.getClass();
       System.out.println(peopleClass1);
       //获取Class方式二
       Class peopleClasss2=Class.forName("reflect.People");
       System.out.println(peopleClasss2);
       //获取Class方式三
       Class peopleClass3=People.class;
       System.out.println(peopleClass3);
  }

3.3、通过反射创建对象

 public static void main(String[] args) throws Exception {
       //获取Class
       Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
       //创建People对象
       People people=peopleClasss.newInstance();
  }

3.4、通过反射访问构造器

public static void main(String[] args) throws Exception {
       //获取Class
       Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
       //获取People的有参构造器
       Constructor<People> constructor=peopleClasss.getConstructor(String.class,int.class);
       //通过有参构造器创建People对象
       People people=constructor.newInstance("yl",18);
       System.out.println(people);
  }

3.5、通过反射操作非静态属性

 public static void main(String[] args) throws Exception {
       //获取Class
       Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
       //创建People对象
       People people=peopleClasss.newInstance();
       //通过Class获取name属性
       Field nameField=peopleClasss.getField("name");
       //设置属性值
       nameField.set(people,"lsy");
       //获取属性值
       String name=(String) nameField.get(people);
       System.out.println(name);
  }

3.6、通过反射操作静态属性

public static void main(String[] args) throws Exception {
       //获取Class
       Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
       //通过Class获取name属性
       Field nameField=peopleClasss.getField("height");
       //设置属性
       nameField.set(null,50.1);
       //获取属性值
       double name=(double) nameField.get(peopleClasss);
       System.out.println(name);
  }

3.7、通过反射调用无参方法

public static void main(String[] args) throws Exception {
       //获取Class
       Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
       //创建People对象
       People people=peopleClasss.newInstance();
       //获取方法
       Method showMethod=peopleClasss.getMethod("show");
       //执行方法
       showMethod.invoke(people);
  }

3.8、通过反射调用有参方法

public static void main(String[] args) throws Exception {
       //获取Class
       Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
       //创建People对象
       People people=peopleClasss.newInstance();
       //获取方法
       Method showMethod=peopleClasss.getMethod("show",String.class);
       //执行方法
       showMethod.invoke(people,"hello");
  }

3.9、通过反射访问私有属性

 public static void main(String[] args) throws Exception {
       //获取Class
       Class peopleClasss=Class.forName("com.yl.reflect.People");
       //创建People对象
       People people=(People) peopleClasss.newInstance();
       //获取age属性
       Field ageField=peopleClasss.getDeclaredField("age");
       //抑制访问检查
       ageField.setAccessible(true);
       //设置age属性值
       ageField.set(people,18);
       System.out.println(people);
  }

3.10、通过反射访问私有方法

public static void main(String[] args) throws Exception {
       //获取Class
       Class peopleClasss=Class.forName("com.yl.reflect.People");
       //创建People对象
       People people=(People) peopleClasss.newInstance();
       //获取私有show方法
       Method showMethod=peopleClasss.getDeclaredMethod("show",int.class);
       //抑制访问检查
       showMethod.setAccessible(true);
       //执行showMethod
       showMethod.invoke(people,7);
  }

3.11、通过反射操作数组

 public static void main(String[] args) throws Exception {
       //通过反射创建数组
       int[] ints= (int[]) Array.newInstance(int.class,3);
       //给数组赋值
       Array.set(ints,0,100);
       Array.set(ints,1,200);
       Array.set(ints,2,300);
       //获取数组的值并输出
       System.out.println(Array.get(ints,0));
       System.out.println(Array.get(ints,1));
       System.out.println(Array.get(ints,2));
  }

 

 

 

 

 

记得快乐
posted @ 2020-08-18 15:01  Y-wee  阅读(196)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3