文章目录
回顾
1.三种创建Class对象的形式
Class.forName("")
类.class
对象.getCalss()
字节文件.class对象
2.Class下面获取构造方法对象的方法
getConstructors();
getDeclaredConstructors();
getConstructor(Class ..... parameterType);
getDeclaredConstructor(Class ..... parameterType);
3.Class下面获取方法对象的方法
getMethods();
getDeclaredMethods();
getMethod(String name, Class .... parameterType);
getDeclaredMethod(String name, Class .... parameterType);
4.Class下面获取属性对象的方法
getFields();
getDeclaredFields();
getField(String name);
getDeclaredField(String name);
5.Constructor对象下面的方法
newInstance(); 通过构造方法创建了实例对象
setAccessible(true);
6.Method对象下面的方法
setAccessible(true);
invoke(Object obj, Object ... param);
7.Field对象下面的方法
setAccessible(true);
set(Object obj, Object value);
8.简单聊聊对反射的理解
今天的内容
1.单例模式
2.序列化操作(IO流)
以下两个是jdk的新特性:
3.lambda表达式
4.Stream流
1.单例模式
Java提供了二十多种设计模式,在咱们教学过程中抽重要的学习,开发中用的
模式并不是一朝一夕学会的东西,工厂模式, 代理模式 策略模式等
设计模式是全球公认的。为了让咱们的代码变得更加简洁,效率更高,产生出来的模式
修改的时候更加方便
单例模式:
要求在整个程序运行过程中,只出现一个实例对象。减少内存的消耗
如何判断两个对象或者多个对象是否是单例,看内存地址。如果内存地址相等的话,绝对是同一个对象。
想一些问题:
创建对象 通过关键字 new 来创建,但是new一次 再new一次对象的内存地址绝对不一样的。就意味着你必须将一个类的构造方法私有化
java
package com.qfedu.f_singleinstance;
class SingDog {
private static SingDog singDog = null;
private SingDog () {
}
public static SingDog getInstance() {
synchronized (SingDog.class) {
if (singDog == null) {
//
singDog = new SingDog();
}
}
return singDog;
}
}
class MyThread1 implements Runnable {
@Override
public void run() {
SingDog instance = SingDog.getInstance();
System.out.println(instance);
}
}
class MyThread2 implements Runnable {
@Override
public void run() {
SingDog instance = SingDog.getInstance();
System.out.println(instance);
}
}
public class Demo1 {
public static void main(String[] args) {
//以上两个对象是两个不同的对象。单例模式的目的
//是只能有一个对象,不能有多个对象,就意味着不能再new
//为啥?new一个就是对象。不能new 在类里面咋写?
//解决方案: 私有话构造方法
//不能new 想得到对象? 在类中定义一个静态方法
//为啥是静态方法 只能用来调用
// SingDog singdog = SingDog.getInstance();
//
// System.out.println(singdog);
// SingDog singdog1 = SingDog.getInstance();
// System.out.println(singdog1);
new Thread(new MyThread1()).start();
new Thread(new MyThread2()).start();
}
}
懒汉式的写法
java
package com.qfedu.a_single;
//懒汉式写法
class Person {
private static Person person;
private Person () {
}
public static synchronized Person getInstance () {
if (person == null) {
person = new Person();
}
return person;
}
}
饿汉式写法
java
package com.qfedu.a_single;
class Cat {
private static final Cat cat = new Cat();
private Cat() {
}
public static Cat getIntance () {
return cat;
}
}
public class Demo3 {
public static void main(String[] args) {
Cat intance = Cat.getIntance();
Cat intance1 = Cat.getIntance();
System.out.println(intance);
System.out.println(intance1);
}
}
懒汉式:线程不安全
饿汉式:线程安全的
效率来说: 饿汉式效率高,因为不用加锁
性能来说: 饿汉式类一加载就实力出来对象。但是懒汉式调用方法的时候才进行创建对象
懒汉式的内存消耗是小于饿汉式的
2.序列化
和IO流有关
类 ObjectInputStream(反序列化) 和 ObjectOutputStream(序列化) 是高层次的数据流,它们包含反序列化和序列化对象的方法。
ObjectOutputStream 类包含很多写方法来写各种数据类型,但是一个特别的方法例外:
public final void writeObject(Object x) throws IOException
上面的方法序列化一个对象,并将它发送到输出流。相似的 ObjectInputStream 类包含如下反序列化一个对象的方法:
public final Object readObject() throws IOException, ClassNotFoundException
该方法从流中取出下一个对象,并将对象反序列化。它的返回值为Object,因此,你需要将它转换成合适的数据类型。
总结:序列化能干嘛? 将一个类对象信息(构造方法,属性,方法)可以写到本地一个文件中。这叫序列化。从文件中读取一个对象的信息,这叫反序列化。
序列化注意事项:
1.被序列化的实体类必须实现一个接口 Serializable,不然不能被序列化
序列化案例:
将一个对象赋值完以后写到到本地。ObjectOutputStream
java
package com.qfedu.b_serialize;
import java.io.*;
import java.util.ArrayList;
public class Demo1 {
public static void main(String[] args) throws Exception {
//序列化:将对象存到一个文件中
Employee employee = new Employee();
employee.name = "马斯克";
employee.address = "月球";
employee.number = 100;
employee.mailCheck();
//将employee对象进行序列化 存到一个文件中 序列化的文件的后缀都是.ser
FileOutputStream fos = new FileOutputStream(new File("c:/aaa/emp.ser"));
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fos);
objectOutputStream.writeObject(employee);
objectOutputStream.close();
fos.close();
System.out.println("写入成功");
}
}
反序列化
将本地的文件信息(被序列化过的)写到一个对象中
ObjectInputStream
java
package com.qfedu.b_serialize;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class Demo2 {
public static void main(String[] args) throws Exception{
//进行反序列化
FileInputStream fis = new FileInputStream(new File("c:/aaa/emp1.ser"));
ObjectInputStream ois = new ObjectInputStream(fis);
Employee emp = (Employee)ois.readObject();
System.out.println(emp.name);
System.out.println(emp.number);
System.out.println(emp.address);
System.out.println(emp.sb);
emp.mailCheck();
}
}
总结:序列化将对象的值存到本地磁盘的文件中以作备份。反序列化可以将本次磁盘序列化过的文件读取到实体类的对象中。
3.Lambda表达式
Lambda表达式被称称为闭包。他是推动了Java8新特性的重要的一步。
Lambda表达式运行函数式编程。就是简化代码的。变得更加简洁,但是可读性特别差
3.1入门案例
java
package com.qfedu.c_lambda;
public class Demo1 {
public static void main(String[] args) {
//新建一个线程
//第一种的创建方式
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("简洁嘻嘻哒" + i);
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("锤人" + i);
}
}
}).start();
//Thread构造方法是接口对象
Runnable runnable = ()-> System.out.println("嘻嘻");
new Thread(runnable).start();
}
}
3.2lambda表达式语法格式
只看接口下面的唯一的一个抽象方法。
接口 接口对象 = ()->表达式; 无参 无返回值的 接口 接口对象 = (parameter)->表达式; 有参 无返回值的 接口 接口对象 = ()->{表达式;}; 无参 有返回值的 接口 接口对象 = (parameter)->{表达式;}; 有参有返回值
3.2.1无参无返回值的形式
java
package com.qfedu.c_lambda;
interface Computer {
void coding();
}
public class Demo4 {
public static void main(String[] args) {
//无参无返回值的
test(() -> System.out.println("敲代码"));
}
//而如果一个方法的参数是一个接口对象的话,难免要new 这个接口 重写方法
public static void test (Computer c) {
c.coding();
}
}
3.2.2有参无返返回值的方法
java
package com.qfedu.c_lambda;
interface C {
void eat(String name, int a);
}
public class Demo5 {
public static void main(String[] args) {
test(( name, a) -> System.out.println(name + "吃" + a) , "狗蛋", 4);
}
public static void test (C c, String name, int a) {
c.eat(name , a);
}
}
3.2.3无参有返回值
java
package com.qfedu.c_lambda;
interface D {
int num();
}
public class Demo6 {
public static void main(String[] args) {
test(() ->{
if (true) {
System.out.println("xixida");
}
return 500;
});
}
public static void test (D d) {
d.num();
}
}
3.2.4有参有返回值的
java
package com.qfedu.c_lambda;
interface E {
int add(int a, int b);
}
public class Demo7 {
public static void main(String[] args) {
test((a, b) -> a + b, 2, 3);
}
public static void test (E e, int a, int b) {
int sum = e.add(a, b);
System.out.println(sum);
}
}