java - day019 - 反射
网络程序,难点在线程
- 反射 reflect
- 实用 类对象 来执行反射操作
- 反射获得一个类的定义信息
- 反射创建对象
- 反射调用成员变量, 方法
- 方法
- 获得类对象的三种方式
- A.class
- Class.forName("完整类名");
- a1.getClass();
- 类对象的方法
- c.getPackage().getName();
- c.getName();
- c.getSimpleName();
- 获得成员变量的定义信息
- getFields(); 得到可见的成员变量,即能访问的, 包括继承来的
- getDeclaredFields(); 本类定义的所有变量, 包括私有变量, 不包括继承的
- getField(变量名); 得到单个可见的的成员变量
- getDeclaredField(变量名);
- 获得构造方法的定义信息
- getConstructors(); 获得可见的构造方法,
- getDeclaredConstructors(); 获得所有的构造方法
- getConstructor(参数类型列表); 获得单个可见的的构造方法
- getDeclaredConstructor(int.class,String.class);
- 获得方法的定义信息
- getMethods(); // 可见的方法, 包括继承的方法
- getDeclaredMethods(); // 本类定义的方法, 包括私有的方法,不包括继承的方法
- getMethod(方法名,参数类型列表);
- getDeclaredMethod(方法名,int.class,String.class);
-
package day1901_反射; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; import java.util.Scanner; public class Test1 { public static void main(String[] args) throws Exception { System.out.println("输入完整类名"); String s = new Scanner(System.in).nextLine(); // 获得这个类的'类对象' Class<?> c = Class.forName(s); // 获得包名, 类名 ,简写类名 String p = c.getPackage().getName(); String n = c.getName(); String sn = c.getSimpleName(); System.out.println(p); System.out.println(n); System.out.println(sn); System.out.println("----成员变量------"); f1(c); System.out.println("----构造方法------"); f2(c); System.out.println("----方法------"); f3(c); } private static void f3(Class<?> c) { /* * Method 对象, 封装方法的定义信息 * public static void f(int i , String s)throws X,Y,Z */ Method[] a = c.getDeclaredMethods(); for (Method f : a) { String n = f.getName(); // 构造方法参数的类型 (int.class, String.class); Class<?>[] p = f.getParameterTypes(); System.out.println(n+"("+Arrays.toString(p)+")"); } } private static void f2(Class<?> c) { /* * Constructor 构造方法的封装对象 * * public A(int a, String s) throws X,Y,Z * */ Constructor<?>[] a = c.getConstructors(); for (Constructor<?> t : a) { String n = c.getSimpleName(); // 构造方法参数的类型 (int.class, String.class); Class<?>[] p = t.getParameterTypes(); System.out.println(n+"("+Arrays.toString(p)+")"); } } private static void f1(Class<?> c) { /* * Field对象 * 封装了成员变量的定义信息 * */ Field[] a = c.getDeclaredFields(); for (Field f : a) { System.out.println(f.getType().getSimpleName()+f.getName()); } } }
- 反射新建对象
- 通过 类对象 的反射操作
- 执行 无参构造 方法
- object obj = c.newInstabce();
- 执行有参构造
- 先获得构造方法
- Constructor t = c.getConstructor(int.class,String.class);
- 通过构造方法的反射操作, 来新建对象
- object obj = t.newInstance(int ,String);
-
package day1901_反射; import java.lang.reflect.Constructor; import java.util.Scanner; public class Test2 { public static void main(String[] args) throws Exception { System.out.println("输入类名"); String s = new Scanner(System.in).nextLine(); Class<?> c = Class.forName(s); Object o1 = null; Object o2 = null; /* * 新建 o1,执行无参构造 * 新建 o2,执行有参构造 */ try { o1 = c.newInstance(); System.out.println("o1:"+o1);// 默认执行 o1 的toString } catch (Exception e) { // TODO: handle exception System.out.println("o1: 不能执行无参构造"); } System.out.println("-----------------------------"); try { Constructor<?> t = c.getConstructor(int.class); o2 = t.newInstance(666); System.out.println("o2: "+o2); } catch (Exception e) { // TODO: handle exception System.out.println("o2: 不能执行int参数构造方法"); } } }
- 反射调用成员变量,
- 获得成员变量
- Field f = c.getDeclaredField("age");
- 使私有变量也可以访问,
- f.setAccssible(true);
- 赋值
- f.set(对象,21);给指定对象的变量赋值
- 取值
- int i = (int)f.get(对象);
-
package day1901_反射; import java.lang.reflect.Field; import day0802.Student; /* * 跨项目不能直接访问,需要项目关联 * 左侧选中需要关联项目的项目,右键弹出选中build path 选中项目project, */ public class Test3 { public static void main(String[] args) throws Exception, SecurityException { // Student s = new Student(); Class<Student> c = Student.class; // 获得age变量 并赋值 Field f = c.getDeclaredField("age"); f.setAccessible(true); f.set(s, 21); System.out.println(s.getAge()); int a = (int)f.get(s); System.out.println(a); } }
- 反射调用成员方法
- 获得方法
- Method t = c.getMethod(方法名,参数类型列表);
- 使得私有方法允许被调用
- t.setAccessible(true);
- 调用方法
- t.invoke(对象,参数数据);
- 让指定对象,执行该方法
- 静态方法,第一个参数传 null
- 没有返回值得到 null
-
package day1901_反射; import java.lang.reflect.Field; import java.lang.reflect.Method; import day0802.Student; /* * 跨项目不能直接访问,需要项目关联 * 左侧选中需要关联项目的项目,右键弹出选中build path 选中项目project, */ public class Test3 { public static void main(String[] args) throws Exception, SecurityException { // Student s = new Student(); Class<Student> c = Student.class; // 获得age变量 并赋值 Field f = c.getDeclaredField("age"); f.setAccessible(true); f.set(s, 21); System.out.println(s.getAge()); int a = (int)f.get(s); System.out.println(a); // 反射测试方法 Method gg = c.getMethod("getGender"); Method sg = c.getMethod("setGender", String.class); sg.invoke(s, "男"); Object r = gg.invoke(s); System.out.println(r); } }
- 反射的测试应用
-
package day1901_反射; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.lang.reflect.Method; import java.util.ArrayList; public class Runner { private static ArrayList<String> list = new ArrayList<String>(); // 静态初始化快 static { try { BufferedReader buf = new BufferedReader( new InputStreamReader( new FileInputStream( "/Users/dingzhijie/Desktop/file3.txt"), "UTF-8")); String line; while ((line = buf.readLine()) != null) { line = line.replace("\\s+", ""); if (line.length()==0) { continue; } list.add(line); } buf.close(); } catch (Exception e) { // TODO: handle exception throw new RuntimeException(e); } } public static void launch() { try { for (String s : list) { // 拆分字符串 String[] a = s.split(";"); // 获得类名 Class<?> c = Class.forName(a[0]); Object obj = c.newInstance(); // 获得方法名 Method m = c.getMethod(a[1]); m.invoke(obj); } } catch (Exception e) { // TODO: handle exception System.out.println("执行失败"); e.printStackTrace(); } } public static void main(String[] args) { System.out.println("main"); for (String string : list) { System.out.println(string); } System.out.println("--------------"); Runner.launch(); } }
- 反射是框架的底层实现原理
- SSM
- 注解
- 为其他开发工具,或其他 Java 程序,提供额外的信息
- @Override
- public String toString(){ }
- @Override 由编译器处理,编译器识别改注解,来对方法重新进行语法检查
- 自定义注解
- 要自己编写处理代码
-
package day1902_注解; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) // 单个 //@Target({ElementType.METHOD,ElementType.FIELD}) // 多个 @Retention(RetentionPolicy.RUNTIME) /* * 元注解 * * @Target * 设置注解目标: 类, 方法,成员变量, 参数... * * @Retention * 保留范围: * 源码文件 - 编译时注解信息被丢弃 - 编译器处理 * 字节码 - 类被加载到内存是丢弃 - 类加载器处理 * 运行期内存 - 在内存中存在,不会被丢弃 - 自定义注解使用 * */ //定义注解 @interface public @interface Test { // 注解的属性 // 如果不指定默认值, 使用时必须赋值 // int id(); int id() default 0; // 特殊的属性名, 有特殊待遇 // 如果单独赋值, 可以不写属性名 String value() default ""; }
- Junit 单元测试框架
- Junit 第三方开源工具
- Junit 是 Java 单元测试的事实标准
- eclipse 集成了Junit, 可以直接在项目中引入 Junit jar 包
- 还集成了 Junit 的运行器
-
package day1903_Junit; import org.junit.Test; /* * 引入Junit 开发包 * 右键点击项目 Build path - library - * add Library - Junit - Junit 4 * * * 直接运行即可测试 * 光标定位在测试方法上, 可以只执行单个测试方法 * 定位在类上是测试单个类的代码 * */ public class Test1 { @Test public void a(){ System.out.println("测试a"); } public void b(){ System.out.println("测试b"); } @Test public void c(){ System.out.println("测试c"); } @Test public void d(){ System.out.println("测试d"); } }
- 网络爬虫
- 抓取网页页面内容
- 常用的网络爬虫工具
- HttpClient
- Jsoup
- Jsoup
- 第三方的开源 API
- 需要到官网下载 Jsoup jar 文件
- 参考官方的使用文档, 示例代码
-
package day1904_网络爬虫; import java.io.IOException; import org.jsoup.Jsoup; import org.junit.Test; /* * 引入 Jsoup 开发包 * 右键点击项目 - Build path - add External jar 选中所有文件 */ public class Test1 { @Test public void test1() throws Exception { String s = Jsoup.connect("http://www.baidu.com") .execute() .body(); System.out.println(s); } @Test public void test2() throws Exception { String s = Jsoup.connect("http://www.jd.com/") .execute() .body(); System.out.println(s); } }
没有那个时代犹如现在,知识的爆发和技术的进步如此的迅速,必须不断的学习才能紧跟时代的步伐 . (PS:资料来源比较复杂 ,如有侵权 , 删)