使用步骤
UserService
public class UserService {
public String login(String userName,String pwd){
if(userName.equals("mahaonan") && pwd.equals("010220")){
return "登录成功";
}else {
return "账号或密码有错误";
}
}
public void selectName(){
System.out.println(1/0);
System.out.println("查询用户名字");
}
}
public class TestUserService {
/*
必须是,无参数,无返回值,非静态方法
*/
@Test
public void testLogin(){
UserService service = new UserService();
String mes = service.login("mahaonan", "010220");
//进行预期结果的正确性测试:断言
Assert.assertEquals("您的业务功能可能有问题","登录成功",mes);
}
@Test
public void testSelectNames(){
UserService service = new UserService();
service.selectName();
}
}
执行完之后的方法:释放资源
Junit常见注解(Junit 5.xxx版本)
public class Test {
@Before
public void before(){
System.out.println("在方法执行前,执行before-------");
}
@After
public void after(){
System.out.println("在方法执行后,执行after-------");
}
@BeforeClass //必须修饰为static静态方法
public static void beforeClass(){
System.out.println("在所有方法执行前,执行该方法beforeClass,只执行一次");
}
@AfterClass //必须修饰为static静态方法
public static void afterClass(){
System.out.println("在所有方法执行后,执行该方法afterClass,只执行一次");
}
}
public class Test {
public static void main(String[] args) throws Exception{
//1.Class类中的一个静态方法来获取Class:forName(全限名)
Class c = Class.forName("junit_reflect_.reflect.Student");
System.out.println(c);
//2.类名.class 来获取
Class c1 = Student.class;
System.out.println(c1);
//3.通过对象.getClass()来获取
Student s = new Student();
Class c2 = s.getClass();
System.out.println(c2);
}
}
【反射的第一步是先获取类对象,然后从类对象中获取类的成分对象】
【获取构造器的作用依然是初始化一个对象返回】
public class Student {
private String name;
private Integer age;
public Student() {
System.out.println("无参构造器");
}
public Student(String name, Integer age) {
System.out.println("有参构造器");
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
public class TestOne {
//1.getContructors:获取全部public修饰的构造器(只能获取public修饰的)
@Test
public void getConstructors(){
Class c = Student.class;
//获取所有public的构造器
Constructor[] constructors = c.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor.getName()+"---->"+constructor.getParameterCount());
}
}
//2.getDeclareConstructors:获取全部的构造器(无论什么修饰)
@Test
public void getDeclareConstructors(){
Class c = Student.class;
//获取所有的构造器
Constructor[] constructors = c.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor.getName()+"---->"+constructor.getParameterCount());
}
}
//3.获取某个构造器,只能获取public修饰的
@Test
public void getConstructor() throws Exception {
Class c = Student.class;
//获取单个public修饰构造器:无参
Constructor constructor = c.getConstructor();
System.out.println(constructor.getName()+"---->"+constructor.getParameterCount());
}
//4.获取某个构造器,无论什么修饰的
@Test
public void getDeclareConstructor() throws Exception {
Class c = Student.class;
//获取单个无所谓修饰构造器:无参
Constructor constructor = c.getDeclaredConstructor();
System.out.println(constructor.getName()+"---->"+constructor.getParameterCount());
//获取单个构造器:有参
Constructor constructorPara = c.getDeclaredConstructor(String.class,Integer.class);
System.out.println(constructorPara.getName()+"---->"+constructorPara.getParameterCount());
}
}
【获取并创建实例对象】
public class TestTwo {
public static void main(String[] args) throws Exception {
//获取无参构造器并创建实例
Class c = Student.class;
Constructor constructor = c.getConstructor();
//遇到私有构造器,可强行暴力反射
constructor.setAccessible(true);//权限被打开
Student s = (Student) constructor.newInstance();
System.out.println(s);
//获取某个有参构造器并创建实例
Constructor constructor1 = c.getConstructor(String.class, Integer.class);
Student s1 = (Student) constructor1.newInstance("马浩楠", 22);
System.out.println(s1);
}
}
public class Student {
private String name;
private Integer age;
public static String schoolName;
public static final String COUNTRY = "中国";
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Student(String name, Integer age) {
System.out.println("有参构造器");
this.name = name;
this.age = age;
}
public Student() {
System.out.println("无参构造器");
}
}
public class Dog {
private String name;
public Dog() {
}
public void run(){
System.out.println("狗正在跑!~");
}
public void eat(){
System.out.println("狗正在吃骨头!");
}
public String eat(String name){
System.out.println("狗正在吃:"+name);
return "吃的很开心";
}
public static void inAddress(){
System.out.println("正在宿舍苦逼学习!");
}
public Dog(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
//获取类中的所有成员方法对象
@org.junit.Test
public void allMethods(){
Class c = Dog.class;
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName()+"---方法返回值类型:"+method.getReturnType()+"---->参数个数:"+method.getParameterCount());
}
}
//获取某个方法
@org.junit.Test
public void singleMethod() throws Exception{
Class c = Dog.class;
Method eat = c.getDeclaredMethod("eat");
Method eat1 = c.getDeclaredMethod("eat",String.class);
Dog dog = new Dog();
//暴力反射
eat.setAccessible(true);
eat1.setAccessible(true);
//没有返回值,返回的结果则为null
Object result = eat.invoke(dog);
System.out.println(result);
Object result1 = eat1.invoke(dog, "骨头");
System.out.println(result1);
}
}
public class Test {
public static void main(String[] args) throws Exception{
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
System.out.println(list1.getClass() == list2.getClass());
System.out.println("----------------------");
ArrayList<Integer> list3 = new ArrayList<>();
list3.add(10);
list3.add(40);
//通过反射,来动态获取该数组,并添加字符串
Class c = list3.getClass();
Method add = c.getDeclaredMethod("add", Object.class);
add.invoke(list3,"马浩楠");
System.out.println(list3);
}
}
需求:参数为任意一个对象,在不清楚对象字段的情况下,可以将对象的字段名和对应的值存储到文件中
Student
public class Student {
private String name;
private char sex;
private int age;
private String className;
private String hobby;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex=" + sex +
", age=" + age +
", className='" + className + '\'' +
", hobby='" + hobby + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public Student() {
}
public Student(String name, char sex, int age, String className, String hobby) {
this.name = name;
this.sex = sex;
this.age = age;
this.className = className;
this.hobby = hobby;
}
}
public class Teacher {
private String name;
private char sex;
private double salary;
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", sex=" + sex +
", salary=" + salary +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public Teacher(String name, char sex, double salary) {
this.name = name;
this.sex = sex;
this.salary = salary;
}
public Teacher() {
}
}
public class MyBatisUtils {
public static void save(Object obj){
try(
PrintStream ps = new PrintStream(new FileOutputStream("E:\\code\\Java_Demos\\Java\\reflect_data.txt",true))
){
//1.提取对象的全部成员变量
Class c = obj.getClass();
//c.getSimpleName()获取当前类名,getName()是全限名(包名+类名)
ps.println("============"+c.getSimpleName()+"============");
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
//获取该变量的名称
String name = field.getName();
field.setAccessible(true);
//获取该名称变量的值
String value = field.get(obj) + "";
ps.println(name+"="+value);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
public class Test {
public static void main(String[] args) {
Student s = new Student("马浩楠",'男',22,"理工","打球");
MyBatisUtils.save(s);
Teacher t = new Teacher("程明辉",'女',3000);
MyBatisUtils.save(t);
}
}
概述
作用
public @interface 注解名称{
数据类型 数据名() [default 默认值];
}
public @interface MyBook {
String name();
String[] authors();
double price();
}
public @interface Book {
String value(); //特殊属性
}
@MyBook(name="Java",authors = {"马浩楠"},price = 200.5)
@Book("MyBatis")
public class AnnotationDemo01 {
@MyBook(name="Java",authors = {"马浩楠"},price = 200.5)
public static void main(String[] args) {
@MyBook(name="Java",authors = {"马浩楠"},price = 200.5)
int age = 22;
}
}
@Target({ElementType.METHOD,ElementType.FIELD}) //元注解
@Retention(RetentionPolicy.RUNTIME) //生命周期:一直存在
public @interface MyTest {
}
【所有的类成分Class、Method、Field、Constructor都实现了AnnotationElement接口他们都拥有解析注解的能力】
案例
AnalysisBook
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AnalysisBook {
String value(); //书名
double price() default 100;
String[] authors();
}
public class AnnotationDemo03 {
@Test
public void parseClass(){
//获取类对象
Class c = BookStore.class;
//判断类上是否存在指定注解
if(c.isAnnotationPresent(AnalysisBook.class)){
//直接获取该注解对象
AnalysisBook analysisBook = (AnalysisBook) c.getDeclaredAnnotation(AnalysisBook.class);
System.out.println(analysisBook.value());
System.out.println(analysisBook.price());
System.out.println(Arrays.toString(analysisBook.authors()));
}
}
@Test
public void parseMethod() throws Exception {
//获取类对象
Class c = BookStore.class;
//获取方法对象
Method method = c.getDeclaredMethod("test");
//判断类上是否存在指定注解
if(method.isAnnotationPresent(AnalysisBook.class)){
//直接获取该注解对象
AnalysisBook analysisBook = method.getDeclaredAnnotation(AnalysisBook.class);
System.out.println(analysisBook.value());
System.out.println(analysisBook.price());
System.out.println(Arrays.toString(analysisBook.authors()));
}
}
}
@AnalysisBook(value = "Java",authors = {"马浩楠"})
class BookStore{
@AnalysisBook(value = "MyBatis",authors = {"程明辉"})
public void test(){
}
}
案例:模拟Junit框架
MyTest注解类同上【只能在方法上使用】
Test
public class AnnotationDemo04 {
@MyTest
public void test01(){
System.out.println("====test01====");
}
public void test02(){
System.out.println("====test02====");
}
@MyTest
public void test03(){
System.out.println("====test03====");
}
public static void main(String[] args) throws Exception {
AnnotationDemo04 a = new AnnotationDemo04();
//获取类对象
Class c = AnnotationDemo04.class;
//获取全部方法
Method[] methods = c.getDeclaredMethods();
//循环判断是否存在注解,存在执行方法
for (Method method : methods) {
if(method.isAnnotationPresent(MyTest.class)){
method.invoke(a);
}
}
}
}
案例:
UserService
public interface UserService {
String login(String userName,String password);
void deleteUsers();
String selectUsers();
}
public class UserServiceImpl implements UserService{
@Override
public String login(String userName, String password) {
long startTime = System.currentTimeMillis();
String result = "登录名和密码错误";
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if("haonan".equals(userName) && "010220".equals(password)){
result = "登录成功";
}
long endTime = System.currentTimeMillis();
System.out.println("login方法耗时:"+(endTime - startTime) /1000.0 +"s");
return result;
}
@Override
public void deleteUsers() {
long startTime = System.currentTimeMillis();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("delete方法耗时:"+(endTime - startTime) /1000.0 +"s");
}
@Override
public String selectUsers() {
long startTime = System.currentTimeMillis();
String result = "查询了许多用户...";
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("login方法耗时:"+(endTime - startTime) /1000.0 +"s");
return result;
}
}
public class Test {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.login("haonan","010220");
userService.deleteUsers();
}
}
存在问题:每个方法都要进行性能统计,存在大量重复的代码
优点
UserService
public interface UserService {
String login(String userName,String password);
void deleteUsers();
String selectUsers();
}
public class UserServiceImpl implements UserService{
@Override
public String login(String userName, String password) {
String result = "登录名和密码错误";
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if("haonan".equals(userName) && "010220".equals(password)){
result = "登录成功";
}
return result;
}
@Override
public void deleteUsers() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String selectUsers() {
String result = "查询了许多用户...";
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
}
public class ProxyUtils {
public static UserService getUserProxy(UserService obj){
return (UserService) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = method.invoke(obj, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName()+"方法耗时:"+(endTime - startTime) /1000.0 +"s");
return result;
}
});
}
}
public class Test {
public static void main(String[] args) {
UserService userService = ProxyUtils.getUserProxy(new UserServiceImpl());
userService.login("haonan","010220");
userService.deleteUsers();
}
}