反射
定义:
反射是 java 开发语言的特征之一,它允许 java 程序对自身进行检查(自审),并能直接操作程序内部属性,即就是将类中的各种成分映射成一个 java 对象,利用反射技术可以对一个类进行解剖,将各个组成部分映射成一个对象,这就是反射。
反射机制:
在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法,这种动态获取信息以及动态调用对象的方法的功能称为 Java 的反射机制。
package com.wlx.day16;
import java.util.Arrays;
public class Demo extends BaseDemo
{
public String username;
private Integer userage;
protected int uid;
public Demo()
{
}
public Demo(String username)
{
}
public Demo(int uid)
{
}
public void hello()
{
helloworld();
}
public void world()
{
}
public static void main(String[] args)throws Exception
{
//Demo demo = new Demo();
Class cl = Class.forName(Demo.class.getName());
// Demo demo = (Demo) cl.newInstance();
//JDK9开始使用下面的方式获取对象
Demo demo = (Demo) cl.getDeclaredConstructor().newInstance();
demo.uid = 123;
demo.username = "tom";
demo.hello();
//获取指定类的所有构造方法,不包括父类的构造方法
System.out.println(Arrays.toString(cl.getDeclaredConstructors()));
//获取指定类的所有构造方法,不包括父类的构造方法
System.out.println(Arrays.toString(cl.getConstructors()));
//获取指定类的所有方法,不包括继承父类的方法
System.out.println(Arrays.toString(cl.getDeclaredMethods()));
//获取指定类的所有方法,包括继承父类的方法
System.out.println(Arrays.toString(cl.getMethods()));
//获取指定类的所有全局变量,不包括继承父类的变量
System.out.println(Arrays.toString(cl.getDeclaredFields()));
//获取指定类的所有被public修饰的全局变量,包括继承父类的变量
System.out.println(Arrays.toString(cl.getFields()));
}
}
模拟 IOC/DI
package com.wlx.day16;
import com.wlx.day15.dao.UsersDao;
import com.wlx.day15.entity.Users;
import com.wlx.day15.service.UsersService;
import java.io.FileInputStream;
import java.util.List;
import java.util.Properties;
public class UserSerivceImplDemo
{
public static void main(String[] args)throws Exception
{
Properties ppt = new Properties();
ppt.load(new FileInputStream("./javasecode/src/cl.properties"));
//IOC/DI spring
String userDaoStr = ppt.getProperty("ud");
Class cl = Class.forName(userDaoStr);
//默认情况下是调用cl对应类的无参数构造方法
UsersDao userDao = (UsersDao) cl.getDeclaredConstructor().newInstance();
String userServiceStr = ppt.getProperty("uds");
Class cls = Class.forName(userServiceStr);
//调用cls对应类的有UserDao参数的构造方法,newInstance()用于传递实参给构造方法
UsersService usersService = (UsersService) cls.getDeclaredConstructor(UsersDao.class).newInstance(userDao);
/*UsersService usersService = new UsersServiceImpl(userDao);*/
List<Users> list = usersService.queryAllInfo();
System.out.println(list);
}
}
注解
关键字:@interface
注解一般使用在类前,方法前,也可以使用在属性前。
package com.wlx.day16;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class JiHeDemo
{
//不显示该属性的所有警告
@SuppressWarnings("ALL")
List list = new ArrayList();
//不显示该方法的所有警告
@SuppressWarnings("ALL")
public void hello(Set set)
{
}
//该方法world()不推荐使用了
@Deprecated
public void world()
{
}
public static void main(String[] args)
{
JiHeDemo jiHeDemo = new JiHeDemo();
jiHeDemo.world();
}
}
自定义注解
package com.wlx.day16;
import java.lang.annotation.Target;
//静态导入
import static java.lang.annotation.ElementType.*;
/**
* 表示该注解可以在什么地方使用
* 此处只可以在类的前面和方法的前面使用该注解
*/
@Target(value = {TYPE,METHOD})
public @interface MyAnnotation
{
}
package com.wlx.day16;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@MyAnnotation
public class JiHeDemo
{
//不显示该属性的所有警告
@SuppressWarnings("ALL")
List list = new ArrayList();
//由于MyAnnotation指定的只能在类前和方法前使用该注册,因此此处编译出错
//@MyAnnotation
String username;
//不显示该方法的所有警告
@SuppressWarnings("ALL")
public void hello(Set set)
{
}
//该方法world()不推荐使用了
@Deprecated
public void world()
{
}
@MyAnnotation
public void haha()
{
}
public static void main(String[] args)
{
JiHeDemo jiHeDemo = new JiHeDemo();
jiHeDemo.world();
}
}
UML (了解)
1.1、UML简介
统一建模语言(Unified Modeling Language,UML)是一种为面向对象系统的产品进行说明、可视化和编制文档的一种标准语言,是非专利的第三代建模和规约语言。UML是面向对象设计的建模工具, 独立于任何具体程序设计语言。
1.2、UML作用
(1)为软件系统建立可视化模型
UML符号具有良好的语义,不会引起歧义;基于UML的可视化模型,使系统结构直观、易于理 解;使用UML进行软件系统的模型不但有利于系统开发人员和系统用户的交流,还有利于系统维 护。模型是系统的蓝图,它可以对开发人员的规划进行补充,模型可以帮助开发人员规划要建的系统。有了正确的模型就可以实现正确的系统设计,保证用户的要求得到满足,系统能在需求改变时站得住脚。对于一个软件系统,模型就是开发人员为系统设计的一组视图。这组视图不仅描述了用户需要的功能,还描述了怎样去实现这些功能。
(2)为软件系统建立构件
UML不是面向对象的编程语言,但它的模型可以直接对应到各种各样的编程语言。例如,它可以使用代码生成器工具将UML模型转换为多种程序设计语言代码,如可生成C++,XML,DTD, JAVA,Visual basic等语言的代码,或使用反向生成器工具将程序源代码转换为UML;甚至还可以生成关系数据库中的表。
(3)为软件系统建立文档
UML可以为系统的体系结构及其所有细节建立文档。不同的UML模型图可以作为项目不同阶段的软件开发文档。
1.3、UML模型/类型
UML系统开发中有三个主要的模型:
功能模型:从用户的角度展示系统的功能,包括用例图。
对象模型:采用对象,属性,操作,关联等概念展示系统的结构和基础,包括类别图、对象图。
动态模型:展现系统的内部行为。包括序列图,活动图,状态图。
1.4、UML主要图形
1.4.1、用例图
描述角色以及角色与用例之间的连接关系。说明是谁要使用系统,以及他们使用该系统可以做些什么。一个用例图包含了多个模型元素,如系统、参与者和用例,并且显示了这些元素之间的各种关系,如泛化、关联和依赖。
泛化:类A继承类B就是泛化,泛化关系使用带实线的三角形箭头表示
关联:类A类B的实例之间存在特定的对应关系,使用带实线的箭头表示
依赖:类A访问类B提供的服务,使用带虚线的箭头表示
角色:用户人形符号表示
用例:表示系统中的某个功能,用椭圆符号表示
1.4.2、类图
类图是描述系统中的类,以及各个类之间的关系的静态视图。能够让我们在正确编写代码以前对系统有一个全面的认识。类图是一种模型类型,确切地说,是一种静态模型类型。类图表示类、接口和它们之间的协作关系。
关联
组合:整体和部分的关系就是组合,使用带实心菱形框的实线表示
聚合:实体和实体之间聚合成另一个实体,使用带空心菱形框的实线表示
1.4.3、对象图
与类图极为相似,它是类图的实例,对象图显示类的多个对象实例,而不是实际的类。它描述的不是类之间的关系,而是对象之间的关系。
1.4.4、活动图
描述用例要求所要进行的活动,以及活动间的约束关系,有利于识别并行活动。能够演示出系统中哪些地方存在功能,以及这些功能和系统中其他组件的功能如何共同满足前面使用用例图建模的商务需求。
1.4.5、状态图
描述类的对象所有可能的状态,以及事件发生时状态的转移条件,可以捕获对象、子系统和系统的生命周期。它可以告知一个对象可以拥有的状态,并且事件(如消息的接收、时间的流逝、错误、条件变为真等)会怎么随着时间的推移来影响这些状态。一个状态图应该连接到所有具有清晰的可标识状态和复杂行为的类;该图可以确定类的行为,以及该行为如何根据当前的状态变化,也可以展示哪些事件将会改变类的对象的状态。状态图是对类图的补充。
1.4.6、序列图(时序图)
序列图是用来显示参与者如何以一系列顺序的步骤与系统的对象交互的模型。顺序图可以用来展示对象之间是如何进行交互的。顺序图将显示的重点放在消息序列上,即强调消息是如何在对象之间被发送和接收的。
1.4.7、协作图
和序列图相似,显示对象间的动态合作关系。可以看成是类图和顺序图的交集,协作图建模对象或者角色,以及它们彼此之间是如何通信的。如果强调时间和顺序,则使用序列图;如果强调上下级关系,则选择协作图;这两种图合称为交互图。
1.4.8、构件图(组件图)
描述代码构件的物理结构以及各种构建之间的依赖关系。用来建模软件的组件及其相互之间的关系,这些图由构件标记符和构件之间的关系构成。在组件图,构件时软件单个组成部分,它可以是一个文件,产品、可执行文件和脚本等。
1.4.9、部署图(配置图)
用来建模系统的物理部署。例如,计算机和设备,以及它们之间是如何连接的。部署图的使用者是开发人员、系统集成人员和测试人员。部署图用于表示一组物理结点的集合及结点间的相互关系,从而建立了系统物理层面的模型。
单例类
1.1、定义
如果一个类始终只能创建/有一个实例,那么这个类就是单例类。
单例类分为:懒汉式和饿汉式。
1.2、编写步骤
懒汉式
1、定义一个属性用于缓存当前类的实例,并且被 private static 修饰。
2、所有构造方法都被 private 修饰。
3、使用静态工厂方法获取当前类的对象。
package com.wlx.day16;
/**
* 懒汉式单例类
*/
public class SingleClass
{
//1、定义一个属性用于缓存当前类的实例,并且被 private static 修饰。
private static SingleClass singleClass;
//2、所有构造方法都被 private 修饰
private SingleClass()
{
}
//3、使用静态工厂方法获取当前类的对象。
public synchronized static SingleClass getInstance()
{
if(singleClass == null)
{
singleClass = new SingleClass();
}
return singleClass;
}
}
饿汉式
1、定义一个属性用于缓存当前类的实例,并且被 private static final 修饰,该属性立刻初始化。
2、所有构造方法都被 private 修饰。
3、使用静态工厂方法获取当前类的对象。
package com.wlx.day16;
/**
* 饿汉式单例类
*/
public class SingleClass1
{
//1、定义一个属性用于缓存当前类的实例,并且被 private static final 修饰,该属性立刻初始化
private static final SingleClass1 singleClass = new SingleClass1();
//2、所有构造方法都被 private 修饰
private SingleClass1()
{
}
//3、使用静态工厂方法获取当前类的对象。
public synchronized static SingleClass1 getInstance()
{
return singleClass;
}
}
单元测试
官方 jar 包下载地址:
Download and Install · junit-team/junit4 Wiki · GitHub
直接使用 IDEA 自带的即可,此处省略。
官方 jar 包下载地址
package com.wlx.day16;
import com.wlx.day15.dao.UsersDao;
import com.wlx.day15.dao.impl.UsersDaoImpl;
import org.junit.Before;
import org.junit.Test;
public class HelloDemo
{
private UsersDao usersDao;
/**
* @Before该注解是一定在@Test注解之前执行的注解
*/
@Before
public void createObj()
{
usersDao = new UsersDaoImpl();
}
/**
* 替代main()方法,所有被@Test修饰的方法都可以使用Junit直接执行测试
*/
@Test
public void hello()
{
System.out.println("hello--->HelloDemo--->");
System.out.println(usersDao.queryAllInfo());
}
}
Debug
Step Over 一行一行的往下走,如果这一行上有方法不会进入方法。
Step Into 如果当前行有方法,可以进入方法内部,一般用于进入自定义方法,不会进入官方类库的方法。
Step Out 从步入的方法内退出到方法调用处,此时方法已执行完毕,只是还没有完成赋值。
JDK 新特性
1.1、1.8 新特性
1、Lambad 表达式
2、Stream API
3、Optional
4、Nashorm 引擎
1.1.1、Lambad 表达式
Lambad 是一个匿名函数,Lambad 表达式可以理解为一段可以传递的代码,使用它可以写出更简洁、更灵活、更紧凑的代码,使 Java 语言表达能力得到了提升。
以前用匿名内部类表示的现在都可以使用 Lambad 表达式来编写。
Lambad 表达式的本质:作为函数式接口的实例。
格式:
形参列表 -> Lambad 函数体
其中:
1、形参列表其实就是接口中抽象方法的形参列表。
2、->Lambad 操作符或箭头操作符,注意是减号加箭头,不是等于号加箭头,和 JS 中有区别的。
3、Lambad 函数体其实就是重写的接口中抽象方法的方法体。
1.1.2、没有 Lambad 表达式
package com.wlx.day16;
import org.junit.Test;
public class NoLambadDemo implements FuncationInterfaceDemo
{
@Test
//重写函数式接口中的方法
@Override
public void hello() {
//匿名内部类实现多线程
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("run()---");
}
};
//普通方法的调用
runnable.run();
}
}
1.1.3、无参数 Lambad 表达式
package com.wlx.day16;
public class LambadDemo
{
public static void main(String[] args) {
//Lambad表达式实现匿名内部类多线程
/*Runnable runnable = () -> {
//run()方法的方法体
System.out.println("Lambad---");
};*/
//简写方式
Runnable runnable = () -> System.out.println("Lambad---");
//普通方法的调用
runnable.run();
//实现函数式接口FuncationInterfaceDemo中的hello()方法
/*FuncationInterfaceDemo ftd = ()->{
//hell()函数函数体
System.out.println("hello()---");
};*/
//简写方式,当方法体中只有一条语句时,大括号可以省略
FuncationInterfaceDemo ftd = () -> System.out.println("hello()---");
ftd.hello();
}
}
1.1.4、有参数 Lambad 表达式
package com.wlx.day16;
public class LambadDemo
{
public static void main(String[] args) {
//匿名内部类
FuncationInterfaceDemo1 fid = new FuncationInterfaceDemo1() {
@Override
public void hello(String str) {
System.out.println("str --- "+str);
}
};
//调用fid中的hello()方法并传递参数
fid.hello("hello---world");
//有参数的Lambad表达式
/*FuncationInterfaceDemo1 ffid = (str) -> {
System.out.println("str *** "+str);
};*/
//简写方式,当参数列表只有一个参数时,小括号可以省略
FuncationInterfaceDemo1 ffid = str -> System.out.println("str *** "+str);
//调用ffid中的hello()方法并传递参数
ffid.hello("腾势汽车");
}
}