黑马程序员 反射

本文详细介绍了Java反射技术的概念、特点以及如何获取字节码对应的实例对象、动态获取指定字节码中的内容(如方法)的实现方法,并通过示例展示了如何调用方法、获取私有方法及静态方法。适用于Java与Android开发人员,帮助提升程序扩展性。

java培训、android培训期待与您交流!

       反射技术
   反射就是把Java类中的各中成分映射成相应的Java类。例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等信息也用一个个Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等也是一个个类。
   Class类代表Java类,它的各个实例对象分别对应各个类在内存中的字节码。一个类被加载到内存中会占用相应的空间,而这些空间里面实际上存放的就是字节码,这一个个空间可分别哦那个一个个对象来表示,而这些对象显然都具有一个相同的类型,即Class。
   九个预定义的Class实例对象:boolean,byte,char,short,int,long,float,double,void.
   获取字节码对应的实例对象(Class类型)的三种方式:
       类名.class-->System.class
       对象.getClass()-->new Date().getClass()
       Class.forName("类名")-->Class.forName("java.util.Date")  注意,在写类名称时要带上对应的包名!这种方式相对好一些,因为不需要明确具体的类或者对象。只要有这个类名称就可以了。
   反射技术的特点:动态获取一个字节码文件对象中的所有内容,包括函数,构造器等。有了这样的技术后可以大大的提高程序的扩展性。
   最常用的对象:Class,字节码文件也是一个对象,用Class来进行描述,想要操作一个字节码文件,必须要先获取字节码文件所对应的对象。
   动态获取指定的字节码中的内容(例如方法):Method[] getMethods(),这是一个返回包含某些Method对象的数组,这些对象反应此Class对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共成员方法,可以拿到多个方法。
                                             Method getMethod(String name,Class<?>... paraneterTypes),返回一个Method对象,它反映此Class对象所表示的类或接口的指定公共成员方法,可以拿到指定的方法,例如,Method method = clazz.getMethod("方法名",参数),如果无参则为null
                                             Method[] getDeclaredMethod(),返回Method对象的一个数组,这些对象反应此Class对象所表示的类或接口声明的所有方法,包括共有,保护,默认(包)访问和私有方法,但不包含继承的方法。
   调用方法可以用invoke()方法,这样,对应的方法就可以运行了。例:Class clazz = Class.forName("cn.itcast.bean.Person");//获取字节码文件对象
         Method method = clazz.getMethod("show",String.class,Int.class)//注意参数的写法为class.参数类型,如果空参数则为null
           Object obj = clazz.newInstance();//通过字节码文件对象的方法newInstance获取指定的字节码文件对象实例
           method.invoke(obj,zhang san,20);//传参数时一定要传入实际参数!无参时为null,method方法可以运行了
              如果调用的是一个静态方法的话,因为静态方法不需要对象,所以:Class clazz = Class.forName("cn.itcast.bean.Person");
                    Method method1 = clazz.getMethod("stcticMethod",null);//调用一个静态方法
                    method1.invoke(null,null);//静态方法不需要对象
         调用私有方法:Class clazz = Class.forName("cn.itcast.bean.Person");//获取字节码文件对象
                 Method method = clazz.getMethod("show",String.class,Int.class)//注意参数的写法为class.参数类型,如果空参数则为null
                //取消权限控制
                method.setAccessible(true);
                   Object obj = clazz.newInstance();//通过字节码文件对象的方法newInstance获取指定的字节码文件对象实例
                   method.invoke(obj,zhang san,20);//传参数时一定要传入实际参数!无参时为null,method方法可以运行了
     演示获取字节码对应的实例对象(Class类型)的三种方式:
package cn.itcast.reflect;

import cn.itcast.bean.Person;

public class ReflectDemo {

 /**
  * @param args
  * @throws Exception
  */
 public static void main(String[] args) throws Exception {
  getClassObject_3();
  
 }
 /**
  * 如何获取一个类的字节码文件对象呢?
  * 1,每一个对象都有一个共性的方法 getClass():这时Object类中的方法。
  */
 public static void getClassObject_1(){
  
  Person p = new Person();
  Class clazz = p.getClass();
  
  
  Person p1 = new Person();
  Class clazz1 = p1.getClass();
  System.out.println(clazz1.getName());
  
  System.out.println(clazz==clazz1);//true,同一个字节码对象
  
 }
 
 /**
  * 获取Class对象的第二种方式。
  * 2,通过数据类型的class属性来获取该类型的字节码文件对象。
  * 相对比第一种方式要简单。
  * 但是这两种都必须先要有Person类才行。
  * 并不有利于扩展。
  *
  */
 public static void getClassObject_2(){
  Class clazz = Person.class;
  
  System.out.println(clazz.getName());
  
 }
 /**
  * 第三中方式:
  * 3,使用Class类中的方法完成。方法:forName(className);
  * 这种方式相对好一些,因为不需要明确具体的类或者对象。只要有这个类名称就可以了。
  * 给定什么样的名称就获取什么样字节码文件对象。
  * 这也是我们最为 常用的获取字节码文件对象的方式。
  *
  * @throws Exception
  */
 public static void getClassObject_3() throws Exception{
  
  Class clazz = Class.forName("cn.itcast.bean.Person");
  
  System.out.println(clazz.getName());
  
  
 } 
}
       演示获取字节码中的方法:
package cn.itcast.reflect;

import java.lang.reflect.Method;

public class ReflectDemo2 {

 /**
  * @param args
  * @throws Exception
  */
 public static void main(String[] args) throws Exception {
  getPrivateFunction();
 }
 
 
 /**
  * 获取一个私有方法。
  * @throws Exception
  */
 public static void getPrivateFunction() throws Exception{
  Class clazz = Class.forName("cn.itcast.bean.Person");
  
  Method method = clazz.getDeclaredMethod("method", null);
  //System.out.println(method);
  
  //访问私有成员会有异常。如果想要访问可以通过暴力访问完成,
  //也就是取消掉权限的控制。
  method.setAccessible(true);
  //注意:一般不要暴力,因为既然私有,就是不建议被外部的访问的。
  
  
  Object obj = clazz.newInstance();
  method.invoke(obj, null);
 }
 
 /**
  * 获取一个带参数的方法并运行。
  * @throws Exception
  */
 public static void getParamterFunction() throws Exception{
  Class clazz = Class.forName("cn.itcast.bean.Person");
  
  Method method = clazz.getMethod("func", int.class,String.class);
  
  Object obj = clazz.newInstance();
  
  method.invoke(obj, 30,"haha");
  
  
  //调用一个静态方法。
  Method method2 = clazz.getMethod("staticFunc", null);
  method2.invoke(null, null);
  
 }
 
 /**
  * 获取单个方法。
  * @throws Exception
  */
 public static void getSingleFunction() throws Exception{
  Class clazz = Class.forName("cn.itcast.bean.Person");
  
  //获取指定名称方法。获取show方法对象。
  Method method = clazz.getMethod("show", null);
  
  
  //通过字节码文件对象的方法newInstance获取指定的字节码文件对象实例。
  Object obj = clazz.newInstance();
  method.invoke(obj, null);
  
 }
 
 /**
  * 动态获取指定字节码文件对象中的内容。
  * 1,获取字节码文件中的方法。
  * @throws Exception
  */
 public static void getFunction() throws Exception{
  
  
  //1,获取指定名称的字节码文件对象。
  Class clazz = Class.forName("cn.itcast.bean.Person");
  
  //2,通过Class类中的方法获取其字节码文件中的所有方法。
  //注意:getMethods方法获取的类中的公有方法。
  Method[] methods = clazz.getMethods();
  
  //可以通过getDeclaredMethods() 获取到指定类中的所有方法,包含私有,但不包含继承的。
  methods = clazz.getDeclaredMethods();
  
  //3,将方法遍历一下。
  for(Method method : methods){
   System.out.println(method);
  }
  
 }
}

 

java培训、android培训期待与您交流!

<think>嗯,用户问的是关于黑马程序员JavaSE笔记,我需要先确认这个资源的具体内容和结构。首先,黑马程序员是知名的IT培训机构,他们的JavaSE笔记应该涵盖Java基础的核心知识点。 接下来,我需要回忆一下JavaSE通常包含哪些内容。比如基础语法、面向对象、集合、IO、多线程、网络编程、反射、注解等等。可能还会包括常用的API和工具类,比如String、日期处理等。 然后,用户可能想知道笔记的结构是否清晰,是否有示例代码,有没有重点难点解析,以及是否适合自学。可能还需要说明笔记的适用人群,比如零基础、有经验的开发者等。 另外,用户可能对如何获取这些笔记感兴趣,是否需要付费,或者是否有公开的版本。但根据版权问题,可能需要建议用户通过正规渠道获取,比如官网或授权的平台。 还要考虑用户的实际需求,他们可能是在准备学习Java,或者复习基础知识,需要一份系统的学习资料。因此,回答中需要强调笔记的系统性和实用性,以及是否包含实战案例或练习题。 可能需要提醒用户,学习JavaSE时不仅要看笔记,还要多写代码,实践才能巩固知识。同时,可以建议结合视频课程或官方文档进行学习,效果会更好。 最后,确保回答结构清晰,分点说明,符合用户的要求,使用中文,并且遵循LaTeX格式的要求,比如行内公式用$...$,独立公式用$$...$$,但在这个问题中可能数学公式较少,但如果有涉及的地方要正确使用。</think>以下是对黑马程序员JavaSE笔记的系统性介绍,按学习路径分层解析: $$JavaSE\ 知识体系 = \{基础语法,\ 面向对象,\ 核心API,\ 高级特性\}$$ 一、基础语法层 1. 环境配置 - JDK安装与`JAVA_HOME`环境变量设置 - 验证命令:`java -version` - 第一个程序: ```java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, 黑马!"); } } ``` 2. 数据类型 - 基本类型:`byte(1B)`, `int(4B)`, `double(8B)`等 - 引用类型:类、接口、数组 - 类型转换规则:自动转换与强制转换 3. 流程控制 - 分支结构:`if-else` / `switch`(注意穿透现象) - 循环结构:`for` / `while` / `do-while` - 示例: ```java for(int i=0; i<10; i++){ if(i % 2 == 0) continue; System.out.println(i); } ``` 二、面向对象层 1. 类与对象 - 类结构: ```java public class Person { // 字段 private String name; // 构造方法 public Person(String name) { this.name = name; } // 方法 public void speak() { System.out.println("我是" + name); } } ``` 2. 三大特性 - 封装:访问修饰符`private/protected/public`的使用 - 继承:`extends`关键字与方法重写规则 - 多态:父类引用指向子类对象,`instanceof`运算符 3. 接口与抽象类 - 接口定义: ```java interface USB { void transferData(); } ``` - 抽象类特性:包含抽象方法和具体实现 三、核心API层 1. 集合框架 - `Collection`体系: $$List \subset Collection,\quad Set \subset Collection,\quad Map \not\subset Collection$$ - 常用实现类:`ArrayList`, `LinkedList`, `HashMap` 2. IO流体系 - 字节流:`InputStream/OutputStream` - 字符流:`Reader/Writer` - 典型应用: ```java try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))){ String line; while((line = br.readLine()) != null){ System.out.println(line); } } ``` 3. 异常处理 - 异常分类:`Error` vs `Exception` - 处理机制: ```java try { // 可能抛出异常的代码 } catch(IOException e) { System.out.println("IO异常:" + e.getMessage()); } finally { // 资源释放 } ``` 四、高级特性层 1. 多线程编程 - 实现方式: - 继承`Thread`类 - 实现`Runnable`接口 - 线程同步:`synchronized`关键字与`Lock`接口 2. 反射机制 - 核心类:`Class`, `Method`, `Field` - 典型应用: ```java Class<?> clazz = Class.forName("com.example.Demo"); Object obj = clazz.newInstance(); Method method = clazz.getMethod("show"); method.invoke(obj); ``` 3. 注解开发 - 元注解:`@Target`, `@Retention` - 自定义注解: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface TestCase { String value() default ""; } ``` 五、学习建议 1. 实践路径: $$编码练习量 \propto 技能掌握程度$$ 2. 调试技巧:熟练使用IDE的断点调试功能 3. 文档查阅:养成查看Java API文档的习惯 该笔记体系具有以下优势: - 代码示例丰富(每个知识点配套$3-5$个案例) - 重点标注明确(使用⚠️符号标记易错点) - 知识图谱完整(包含$200+$个核心知识点) 建议通过官方渠道获取最新版本笔记,配套视频教程学习效果更佳。学习过程中注意建立代码仓库(建议使用Git),定期进行阶段性项目实践。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值