1.获取person类中age属性
//获取person中age属性并使用
private static void method4() throws Exception{
// 1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名
Class class1 = Class.forName("com.itheima.classtest.Person");
//2.获取age属性并且使用 参数:获取哪个属性
Field field = class1.getDeclaredField("age");
//3.由于age是私有的 所以需要暴力反射
field.setAccessible(true);
//4.通过构造方法获取person的实例
Constructor constructor = class1.getConstructor();
Object obj = constructor.newInstance();
//5.给age赋值
field.set(obj, 11);
System.out.println(obj);
}
2.获取person类中方法
//获取person类中方法 不包括父类
private static void method2() throws Exception{
// 1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名
Class class1 = Class.forName("com.itheima.classtest.Person");
//2.获取方法 包含私有的
Method[] declaredMethods = class1.getDeclaredMethods(); //当前类所有方法 包括私有 不包括父类
//3.遍历
for (Method method : declaredMethods) {
System.out.println(method);
}
}
//获取person类中方法
private static void method1()throws Exception {
// 1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名
Class class1 = Class.forName("com.itheima.classtest.Person");
//2.获取方法
Method[] methods = class1.getMethods(); //☆☆☆ 获取的是当前类和父类的方法
//3.遍历
for (Method method : methods) {
System.out.println(method);
}
}
3.获取person类中单个方法并且使用
// 获取person类中私有方法 并调用
private static void method5() throws Exception {
// 1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名
Class class1 = Class.forName("com.itheima.classtest.Person");
// 2.获取show方法 让该方法调用 参数1:到底要反射哪个方法
Method method = class1.getDeclaredMethod("funtion");
method.setAccessible(true);
// 3.通过构造方法获取person的实例
Constructor constructor = class1.getConstructor();
Object obj = constructor.newInstance();
// 4.让show方法执行
method.invoke(obj);
}
// 获取person类中show2()
private static void method4() throws Exception {
// 1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名
Class class1 = Class.forName("com.itheima.classtest.Person");
// 2.获取show方法 让该方法调用 参数1:到底要反射哪个方法
Method method = class1.getMethod("show2", String.class);//里面放方法名,参数.calss
// 3.通过构造方法获取person的实例
Constructor constructor = class1.getConstructor();
Object obj = constructor.newInstance();
// 4.让show方法执行
method.invoke(obj, "lxr");
}
// 获取person类中show()
private static void method3() throws Exception {
// 1.获取person类的字节码对象(Class) 参数1:要反射类的完整包名 类名
Class class1 = Class.forName("com.itheima.classtest.Person");
// 2.获取show方法 让该方法调用 参数1:到底要反射哪个方法
Method method = class1.getMethod("show");
// 3.通过构造方法获取person的实例
Constructor constructor = class1.getConstructor();
Object obj = constructor.newInstance();
// 4.让show方法执行
method.invoke(obj);
}
4.反射应用场景1
public class Test {
public static void main(String[] args) throws Exception{
//1.读取配置文件
Properties properties = new Properties();
//2.加载配置文件
properties.load(new FileInputStream("use.properties"));
//3.根据键获取到对应的值
String className = (String) properties.get("className");
String methodName = (String) properties.get("methodName");
//4.让className的methodName执行
Class class1 = Class.forName(className);
//5.获取类中的方法让其执行
Method method = class1.getMethod(methodName);
//6.通过构造方法获取实例
Constructor constructor = class1.getConstructor();
Object obj = constructor.newInstance();
//7.调用方法
method.invoke(obj);
}
}
把要执行的类和方法写到一个配置文件中 创建一个use.properties文件 内容如下
className=com.itheima.app1.Worker
methodName=work
5.反射应用场景2
public class ReflectApp2 {
public static void main(String[] args) throws Exception{
//1.创建list集合
List<Integer> list = new ArrayList<>();
//2.往集合里添加一个元素
list.add(1);
//3.需求:添加String 用反射来实现 object
Class class1 = list.getClass();
//4.通过反射获取要执行 的方法
Method method = class1.getMethod("add", Object.class);
//5.让add方法执行
method.invoke(list, "lxr");//这里的list代表的是系统的
List类的实例
System.out.println(list);
}
}
6.单元测试
1.就是在你想测试的方法上面加上一个符号 @Test @before @after
2.添加jnuit4jar包
7.注解
7.1jdk中提供的几个注解
①suppresswarnings("all") 压制警告
②override 重写父类方法
③deprecated 代表过时
7.2 自定义注解. class interface enum 语法: @interface + 注解名
注解:注解不是注释,注解相当于是一种标记,加上这个标记就做对应的事. 这个标记可以应用到类上 方法上 属性上 包上...
7.3 自定义注解的属性
语法:返回值类型 属性名();
Invalid type Date for the annotation attribute CustomAnno.testStr; only primitive type, String, Class, annotation, enumeration are permitted or 1-dimensional arrays thereof
注解的自定义属性只能是
基本数据类型 String Class 注解 枚举 1维数组
7.4 自定义注解属性细节. 当定义的属性只有一个 并且属性名叫 value 的时候,在使用属性的时候 属性名可以省略.
8.注解应用场景
public class Test {
/**
* 1 .反射person类
* 2 获取person类中所有的方法 判断哪个方法加上了注解
* 3.如果方法上有注解 就让带注解的方法执行
*
* @param args
*/
public static void main(String[] args) throws Exception {
//1.获取person的Class对象
Class class1 = Person.class;
//2.获取person类中所有的方法
Method[] methods = class1.getMethods();
//3.遍历
for (Method method : methods) {
//4.判断一下哪个方法带@myTest这个注解
boolean flag = method.isAnnotationPresent(myTest.class);
//5.为true的 让方法执行
if (flag) {
//6.获取person实例
Constructor constructor = class1.getConstructor();
Object obj = constructor.newInstance();
//6.让方法执行
method.invoke(obj);
}
}
}
}
9.xml语言介绍
①可以描述现实生活中的数据
②可以作为应用程序的配置文件 比如android工程的布局文件.
③作为应用程序传输的数据格式
常见的码表 assic
美国原版
--->iso-8859-1
西欧版--->gbk gb2312(收录汉字不一样多)
中国版--->utf-8
国际通用版;
①直接使用eclipse创建既可
②文档声明 <?xml version="1.0" encoding="UTF-8"?>
③ xml对大小写敏感 开始标签和结束标签成对出现 xml必须有且仅有一个根标签 属性值必须加引号
④ xml中注释 <!-- -->
⑤ cdata区里面的内容不会被解析器解析
10.xml解析技术介绍
1.dom 特点:把整个xml文件加载到内存中,会在内存中形成一颗树形结构.
优点:可以进行增删改查逻辑
缺点:会造成内存溢出.
2.sax
特点:一行一行解析 边解析边释放.
优点:它不会造成内存溢出
缺点:它只能查,不能实现增 删 改.
3.xmlpull 是android中内置解析器. 它解析原理 类似sax.
(区别:sax一开始解析就必须全部解析完,xmlpull更智能一些,可以自己控制)
4.
xmlpull
代码实现
☆
☆
☆ 由于xmlpull解析技术是android的技术所以这个技术默认只能在android工程中使用.
@Test
public void xmlpullParser2() throws Exception{
//1.创建xml解析器的工厂 通过查看api文档得知
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//2.通过工厂的实例 获取xml解析器
XmlPullParser parser = factory.newPullParser();
//3.告诉解析器要解析哪个文件
parser.setInput(new FileInputStream("bookstore.xml"), "utf-8");
//4.获取要解析文件的事件类型 sax是基于事件解决
int eventType = parser.getEventType();
//5.通过循环来解析xml文件 没有解析到文件结尾就一直解析 1阅读性查
while(eventType!= XmlPullParser.END_DOCUMENT){
if ("name".equals(parser.getName())) {
String name = parser.nextText();
System.out.println("name:"+name);
}else if ("price".equals(parser.getName())) {
String price = parser.nextText();
System.out.println("price:"+price);
}
eventType = parser.next();
}
}
5.把解析出来的数据封装到集合List. 为什么要封装到集合里.目的就是为了方便展示信息.
@Test
public void xmlpullParser3() throws Exception {
// 0.创建一个集合 javabean entity
List<Book> lists = null;
Book book = null;
// 1.创建xml解析器的工厂 通过查看api文档得知
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
// 2.通过工厂的实例 获取xml解析器
XmlPullParser parser = factory.newPullParser();
// 3.告诉解析器要解析哪个文件
parser.setInput(new FileInputStream("bookstore.xml"), "utf-8");
// 4.获取要解析文件的事件类型 sax是基于事件解决
int eventType = parser.getEventType();
// 5.通过循环来解析xml文件 没有解析到文件结尾就一直解析 1阅读性查
while (eventType != XmlPullParser.END_DOCUMENT) {
// 6.具体判断一下到底解析的是开始标签还是结束标签
switch (eventType) {
case XmlPullParser.START_TAG: //代表解析的是开始标签
//6.1 具体判断一下到底是哪个开始标签
if ("bookstore".equals(parser.getName())) {
//6.2 初始化list集合
lists = new ArrayList<>();
}else if ("book".equals(parser.getName())) {
//6.3创建book对象
book = new Book();
}else if ("name".equals(parser.getName())) {
//6.4 获取name对应数据
String name = parser.nextText();
book.setName(name);
}else if ("price".equals(parser.getName())) {
//6.4 获取name对应数据
String price = parser.nextText();
book.setPrice(price);
}
break;
case XmlPullParser.END_TAG: //代表解析的是结束标签
if ("book".equals(parser.getName())) {
//6.5 把book对象加入到list集合
lists.add(book);
}
break;
}
//不停的解析
eventType = parser.next();
}
//7 当while循环结束后 我们看list集合里面有几本书
for (Book book2 : lists) {
System.out.println(book2);
}
}
11.今天总结
1.反射 代码要掌握 ☆
☆
☆
2.反射应用场景
☆
☆
☆
3.单元测试 就是在一个方法上加上一个@Test
☆
☆
☆
4.注解
☆
☆
☆ 自定义注解@interface + 注解名 自定义注解属性 元注解
5. 使用注解和反射模拟单元测试
☆
☆
☆
6.xml 语法了解
☆
7.xml 解析技术
☆
☆
dom sax xmlpull解析器
8.通过代码实现xml解析
☆
☆
☆
1.反射
过程:
1.获取class(
Class
.
forName
(
"com.itheima.classtest.Person"
);
)
2.获取实例(
Field
field
=
class1
.
getDeclaredField
(
"age"
);
方法:method、构造:constuctor、成员:field)
3.私有的话(如上加
Declared,后面在加暴力反射
method
.
setAccessible
(
true
);
)
4.如果调用方法或给成员赋值的话需要先实例化(
Constructor
constructor
=
class1
.
getConstructor
();
Object
obj
=
constructor
.
newInstance
();
)
5.给成员赋值用的是set,赋值过程比较诡异,不记得了就要回去看。(
field
.
set
(
obj
,
11
);
System
.
out
.
println
(
obj
);
)
6.调用单个方法时要用invoke方法(
Constructor
constructor
=
class1
.
getConstructor
();
Object
obj
=
constructor
.
newInstance
();
// 4.让show方法执行
method
.
invoke
(
obj
);
)
单词:上面黄色标记的都要记。
2.反射应用场景
①app1(原代码位置:com.itheima.app1)
用一个配置文件
use.properties
记录要执行的类名和方法名,有一个工人类(worker)没有写,里面定义了一个输出的work方法。
className=com.itheima.app1.Worker
methodName=work
public class Test {
public static void main(String[] args) throws Exception{
//1.读取配置文件
Properties properties = new Properties();
//2.加载配置文件
properties.load(new FileInputStream("use.properties"));
//3.根据键获取到对应的值
String className = (String) properties.get("className");
String methodName = (String) properties.get("methodName");
//4.让className的methodName执行
Class class1 = Class.forName(className);
//5.获取类中的方法让其执行
Method method = class1.getMethod(methodName);
//6.通过构造方法获取实例
Constructor constructor = class1.getConstructor();
Object obj = constructor.newInstance();
//7.调用方法
method.invoke(obj);
}
}
②app2
当集合用泛型固定只能放integer类型时,运用反射就可以放其他类型,搞事情,然并卵的功能。
package com.itheima.app2;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class ReflectApp2 {
public static void main(String[] args) throws Exception{
//1.创建list集合
List<Integer> list = new ArrayList<Integer>();
//2.往集合里添加一个元素
list.add(1);
//3.需求:添加String 用反射来实现 object
Class class1 = list.getClass();
//4.通过反射获取要执行 的方法
Method method = class1.getMethod("add", Object.class);
//5.让add方法执行
method.invoke(list, "lxr");
System.out.println(list);
}
3.单元测试
用一个
@Test @before @after测试一个没有main方法的程序。
需要导包
jnuit4jar
4.注解
系统有的注解:
①suppresswarnings("all") 压制警告
②override 重写父类方法
③deprecated 代表过时
自定义注解:
语法: @interface + 注解名
1.获取注解对象的Class
2.获取注解对象中的所有方法
Method[]
methods
=
class1
.getMethods();
3.遍历methods数组,并判断数组里面的方法是否添加本注解
boolean
flag = method.isAnnotationPresent(myTest.
class
);
(注意:
myTest自己就定义在需要添加注解的对象的类里,内部类形式)
@Target
(ElementType.METHOD)
//设置目标的元注解(注解的注解),这里是METHOD,表明该注解只作用在方法上,这段可以不加,不加表示什么地方都可以用该注解
@Retention(RetentionPolicy.RUNTIME)
//这个也是元注解,这个必须加,不加的话上面遍历不到加了注解的方法。
public @interface myTest{
}
4.如果flag为true,建立注解对象的实例,并实现该方法。
5.xml解析
先导包,当天资料里面的xmlpull-jar,复制,然后在Java项目里新建文件夹lib,然后粘贴进去,然后点右键中的build path,做两个奶瓶就可以用了,
右键点开时截不了图,只有这个了
。json也是一样,先导包。
然后将xml文件传进去,注意,直接复制,然后
点项目名粘贴,我吃了大苦头。
1.看xml中的属性类型,根据他建立一个类,这里是
建立一个Book类,创建一个装Book类对象的集合。
2.建立xml解析器的工厂:
XmlPullParserFactory
factory
=
XmlPullParserFactory
.
newInstance
();
parser.setInput(new FileInputStream("bookstore.xml"), "utf-8");
3.通过工厂获取xml解析器
XmlPullParser parser = factory.
newPullParser
();
4.传入要解析的文件
parser.setInput(new FileInputStream("bookstore.xml"), "utf-8");
5.获取事件的代表的返回数值(读到xml开 是0,结束是1,标签是2,数据是4)
int
eventType
=
parser
.
getEventType();
<?xml version="1.0" encoding="UTF-8"?>//getEventType()读到这里是0
<bookstore>//读到这里是2,注意,读到<...>后面的回车也算作文档,返回4
<book id="1">//这里读到book也是2
<name>java基础</name>//读到<name>是2,java基础是4
<price>80</price>
</book>
<book id="2">
<name>android基础</name>
<price>180</price>
</book>
</bookstore>//最后面的标签是2,读完最后一个标签再读就是1
6.判断事件是否结束,为1代表结束,
XmlPullParser
.
END_DOCUMENT 这个就是一个数值为1 的枚举,没结束就读下一个,然后循环
eventType
=
parser
.
next
();
7.循环里面用if判断是否为自己想想要的数据,是的话就读出来。
parser
.
nextText
();//这是获取下一个位置数据的方法,返回String类型
6.json解析
json是键值对的形式存的
JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
JSON 是轻量级的文本数据交换格式
JSON 独立于语言
JSON 具有自我描述性,更易理解
JSON 比 XML 更小、更快,更易解析
数据在名称/值对中
数据由逗号分隔 ,
花括号保存对象 {}
方括号保存数组 []
解析:
1.先导包,上面xmlpull里面讲了
2.建一个json模拟
String testJson = "[{name:'xiaoli',age:'18',sex:'男'},{name:'xiaohong',age:'28',sex:'nv'}]";
3.建一个json数组,将json模拟的数据传进去,然后将他的实例传到具体对象里面去。
JSONArray jsonArray = new JSONArray(testJson);
JSONObject jsonObject = (JSONObject) jsonArray.get(1);
4.通过健取值:
String name = (String) jsonObject.get("name");
String age = (String) jsonObject.get("age");
System.out.println(name+"--"+age);
补充:
11.今天总结
1.反射 代码要掌握 ☆
☆
☆
2.反射应用场景
☆
☆
☆
3.单元测试 就是在一个方法上加上一个@Test
☆
☆
☆
4.注解
☆
☆
☆ 自定义注解@interface + 注解名 自定义注解属性 元注解
5. 使用注解和反射模拟单元测试
☆
☆
☆
6.xml 语法了解
☆
7.xml 解析技术
☆
☆
dom sax xmlpull解析器
8.通过代码实现xml解析
☆
☆
☆