JAVA笔记(十五)

  1. 键盘录入对象,要自定义结束标志,如果是文件,就不必定义结束文件。
  2. Tcp协议代码

package cn.itcast_06;

import java.io.IOException;

import java.io.OutputStream;

import java.net.Socket;

/*

* TCP协议发送数据:

* A:创建发送端的Socket对象

*               这一步如果成功,就说明连接已经建立成功了。

* B:获取输出流,写数据

* C:释放资源

*

* 连接被拒绝。TCP协议一定要先看服务器。

* java.net.ConnectException: Connection refused: connect

*/

public class ClientDemo {

public static void main(String[] args) throws IOException {

// 创建发送端的Socket对象

// Socket(InetAddress address, int port)

// Socket(String host, int port)

// Socket s = new Socket(InetAddress.getByName("192.168.12.92"), 8888);

Socket s = new Socket("192.168.12.92", 8888);

// 获取输出流,写数据

// public OutputStream getOutputStream()

OutputStream os = s.getOutputStream();

os.write("hello,tcp,我来了".getBytes());

// 释放资源

s.close();

}

}

package cn.itcast_06;

import java.io.IOException;

import java.io.InputStream;

import java.net.ServerSocket;

import java.net.Socket;

/*

* TCP协议接收数据:

* A:创建接收端的Socket对象

* B:监听客户端连接。返回一个对应的Socket对象

* C:获取输入流,读取数据显示在控制台

* D:释放资源

*/

public class ServerDemo {

public static void main(String[] args) throws IOException {

// 创建接收端的Socket对象

// ServerSocket(int port)

ServerSocket ss = new ServerSocket(8888);

// 监听客户端连接。返回一个对应的Socket对象

// public Socket accept()

Socket s = ss.accept(); // 侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。

// 获取输入流,读取数据显示在控制台

InputStream is = s.getInputStream();

byte[] bys = new byte[1024];

int len = is.read(bys); // 阻塞式方法

String str = new String(bys, 0, len);

String ip = s.getInetAddress().getHostAddress();

System.out.println(ip + "---" + str);

// 释放资源

s.close();

// ss.close(); //这个不应该关闭

}

}

  1. 多线程tcp传输代码

package cn.itcast_15;

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.Socket;

public class UserThread implements Runnable {

private Socket s;

public UserThread(Socket s) {

this.s = s;

}

@Override

public void run() {

try {

// 封装通道内的流

BufferedReader br = new BufferedReader(new InputStreamReader(

s.getInputStream()));

// 封装文本文件

// BufferedWriter bw = new BufferedWriter(new

// FileWriter("Copy.java"));

// 为了防止名称冲突

String newName = System.currentTimeMillis() + ".java";

BufferedWriter bw = new BufferedWriter(new FileWriter(newName));

String line = null;

while ((line = br.readLine()) != null) { // 阻塞

bw.write(line);

bw.newLine();

bw.flush();

}

// 给出反馈

BufferedWriter bwServer = new BufferedWriter(

new OutputStreamWriter(s.getOutputStream()));

bwServer.write("文件上传成功");

bwServer.newLine();

bwServer.flush();

// 释放资源

bw.close();

s.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

package cn.itcast_15;

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.Socket;

public class UploadClient {

public static void main(String[] args) throws IOException {

// 创建客户端Socket对象

Socket s = new Socket("192.168.12.92", 11111);

// 封装文本文件

// BufferedReader br = new BufferedReader(new FileReader(

// "InetAddressDemo.java"));

BufferedReader br = new BufferedReader(new FileReader(

"ReceiveDemo.java"));

// 封装通道内流

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(

s.getOutputStream()));

String line = null;

while ((line = br.readLine()) != null) { // 阻塞

bw.write(line);

bw.newLine();

bw.flush();

}

// Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了

s.shutdownOutput();

// 接收反馈

BufferedReader brClient = new BufferedReader(new InputStreamReader(

s.getInputStream()));

String client = brClient.readLine(); // 阻塞

System.out.println(client);

// 释放资源

br.close();

s.close();

}

}

package cn.itcast_15;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

public class UploadServer {

public static void main(String[] args) throws IOException {

// 创建服务器Socket对象

ServerSocket ss = new ServerSocket(11111);

while (true) {

Socket s = ss.accept();

new Thread(new UserThread(s)).start();

}

}

}

  1. 三种获取Class对象的方法

A:三种获取Class对象的方式

1:Person p = new Person();

Class c = p.getClass();

2:Class c2 = Person.class;

任意数据类型都具备一个class静态属性,看上去要比第一种方式简单.

3:将类名作为字符串传递给Class类中的静态方法forName即可

Class c3 = Class.forName("Person");

4:第三种和前两种的区别

前两种你必须明确Person类型.

后面是你我这种类型的字符串就行.这种扩展更强.我不需要知道你的类.我只提供字符串,按照配置文件加载就可以了

package cn.itcast_01;

/*

* 反射:就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法。

* * Person p = new Person();

* p.使用

* * 要想这样使用,首先你必须得到class文件对象,其实也就是得到Class类的对象。

* Class类:

*               成员变量  Field

*               构造方法  Constructor

*               成员方法  Method

* * 获取class文件对象的方式:

* A:Object类的getClass()方法

* B:数据类型的静态属性class

* C:Class类中的静态方法

*               public static Class forName(String className)

*  一般我们到底使用谁呢?

*               A:自己玩   任选一种,第二种比较方便

*               B:开发 第三种

*                      为什么呢?因为第三种是一个字符串,而不是一个具体的类名。这样我们就可以把这样的字符串配置到配置文件中。

*/

public class ReflectDemo {

public static void main(String[] args) throws ClassNotFoundException {

// 方式1

Person p = new Person();

Class c = p.getClass();

Person p2 = new Person();

Class c2 = p2.getClass();

System.out.println(p == p2);// false

System.out.println(c == c2);// true

// 方式2

Class c3 = Person.class;

// int.class;

// String.class;

System.out.println(c == c3);

// 方式3

// ClassNotFoundException

Class c4 = Class.forName("cn.itcast_01.Person");

System.out.println(c == c4);

}

}

  1. 反射正常情况下是不能访问私有的,但是可以通过setAccessible()方法就可以访问了(暴力访问,取消访问检查),该方法要放在实际调用之前。
  2. 通过反射获取方法有点特殊,不加Declared,获取的是父类和自己的公共方法,加了获取的是自己的方法。
  3. 泛型的默认类型是object类型,泛型是给编译器看得,运行的时候就不存在了。
  4. 开发的一个原则是:对修改关闭,对扩展开放。
  5. 动态代理

在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib

Proxy类中的方法创建动态代理类对象

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

最终会调用InvocationHandler的方法

InvocationHandler

Object invoke(Object proxy,Method method,Object[] args)

Proxy类中创建动态代理对象的方法的三个参数;

ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载

Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了

InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上

每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的invoke 方法来进行调用。

InvocationHandler接口中invoke方法的三个参数:

proxy:代表动态代理对象

method:代表正在执行的方法

args:代表调用目标方法时传入的实参

Proxy.newProxyInstance

创建的代理对象是在jvm运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,

也不是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,并且命名方式都是这样的形式,

以$开头,proxy为中,最后一个数字表示对象的标号。

System.out.println(u.getClass().getName());

  1. 通过反射获取所有的方法

package cn.itcast_04;

import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

public class ReflectDemo {

public static void main(String[] args) throws Exception {

// 获取字节码文件对象

Class c = Class.forName("cn.itcast_01.Person");

// 获取所有的方法

// Method[] methods = c.getMethods(); // 获取自己的包括父亲的公共方法

// Method[] methods = c.getDeclaredMethods(); // 获取自己的所有的方法

// for (Method method : methods) {

// System.out.println(method);

// }

Constructor con = c.getConstructor();

Object obj = con.newInstance();

/*

* Person p = new Person(); p.show();

*/

// 获取单个方法并使用

// public void show()

// public Method getMethod(String name,Class<?>... parameterTypes)

// 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型

Method m1 = c.getMethod("show");

// obj.m1(); // 错误

// public Object invoke(Object obj,Object... args)

// 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数

m1.invoke(obj); // 调用obj对象的m1方法

System.out.println("----------");

// public void method(String s)

Method m2 = c.getMethod("method", String.class);

m2.invoke(obj, "hello");

System.out.println("----------");

// public String getString(String s, int i)

Method m3 = c.getMethod("getString", String.class, int.class);

Object objString = m3.invoke(obj, "hello", 100);

System.out.println(objString);

// String s = (String)m3.invoke(obj, "hello",100);

// System.out.println(s);

System.out.println("----------");

// private void function()

Method m4 = c.getDeclaredMethod("function");

m4.setAccessible(true);

m4.invoke(obj);

}

}   (原方法没有写出,获取构造方法和字段何其类似)

  1. 动态代理机制的代码

ackage cn.itcast_06;

/*

* 用户操作接口

*/

public interface UserDao {

public abstract void add();public abstract void delete();

public abstract void update();public abstract void find();

}

package cn.itcast_06;

public class UserDaoImpl implements UserDao {

@Override

public void add() {

System.out.println("添加功能");

}

@Override

public void delete() {

System.out.println("删除功能");

}

@Override

public void update() {

System.out.println("修改功能");

}

@Override

public void find() {

System.out.println("查找功能");

}

}

package cn.itcast_06;

public interface StudentDao {

public abstract void login();public abstract void regist();

}

package cn.itcast_06;

public class StudentDaoImpl implements StudentDao {

@Override

public void login() {

System.out.println("登录功能");

}

@Override

public void regist() {

System.out.println("注册功能");

}

}

package cn.itcast_06;

import java.lang.reflect.Proxy;

public class Test {

public static void main(String[] args) {

UserDao ud = new UserDaoImpl();

ud.add();ud.delete();ud.update();ud.find();

System.out.println("-----------");

// 我们要创建一个动态代理对象

// Proxy类中有一个方法可以创建动态代理对象

// public static Object newProxyInstance(ClassLoader loader,Class<?>[]

// interfaces,InvocationHandler h)

// 我准备对ud对象做一个代理对象

MyInvocationHandler handler = new MyInvocationHandler(ud);

UserDao proxy = (UserDao) Proxy.newProxyInstance(ud.getClass()

.getClassLoader(), ud.getClass().getInterfaces(), handler);

proxy.add();proxy.delete();proxy.update();proxy.find();

System.out.println("-----------");

StudentDao sd = new StudentDaoImpl();

MyInvocationHandler handler2 = new MyInvocationHandler(sd);

StudentDao proxy2 = (StudentDao) Proxy.newProxyInstance(sd.getClass()

.getClassLoader(), sd.getClass().getInterfaces(), handler2);

proxy2.login();

proxy2.regist();

}

}

  1. 经典代码

package cn.itcast.test;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.ArrayList;

/*

* 我给你ArrayList<Integer>的一个对象,我想在这个集合中添加一个字符串数据,如何实现呢?

*/

public class ArrayListDemo {

public static void main(String[] args) throws NoSuchMethodException,

SecurityException, IllegalAccessException,

IllegalArgumentException, InvocationTargetException {

// 创建集合对象

ArrayList<Integer> array = new ArrayList<Integer>();

// array.add("hello");

// array.add(10);

Class c = array.getClass(); // 集合ArrayList的class文件对象

Method m = c.getMethod("add", Object.class);

m.invoke(array, "hello"); // 调用array的add方法,传入的值是hello

m.invoke(array, "world");

m.invoke(array, "java");System.out.println(array);

}

}

  1. 通过配置文件访问对象

package cn.itcast.test;

import java.io.FileReader;

import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

import java.util.Properties;

/*

* 通过配置文件运行类中的方法

** 反射:

*               需要有配置文件配合使用。

*               用class.txt代替。

*               并且你知道有两个键。

*                      className

*                      methodName

*/

public class Test {

public static void main(String[] args) throws Exception {

// 反射前的做法

// Student s = new Student();

// s.love();

// Teacher t = new Teacher();

// t.love();

// Worker w = new Worker();

// w.love();

// 反射后的做法

// 加载键值对数据

Properties prop = new Properties();

FileReader fr = new FileReader("class.txt");

prop.load(fr);

fr.close();

/ /获取数据

String className = prop.getProperty("className");

String methodName = prop.getProperty("methodName");

// 反射

Class c = Class.forName(className);

Constructor con = c.getConstructor();Object obj = con.newInstance();

// 调用方法

Method m = c.getMethod(methodName);

m.invoke(obj);

}

}

  1. 通过自定义方法给任意变量赋值代码

package cn.itcast.test;

import java.lang.reflect.Field;

public class Tool {

public void setProperty(Object obj, String propertyName, Object value)

throws NoSuchFieldException, SecurityException,

IllegalArgumentException, IllegalAccessException {

// 根据对象获取字节码文件对象

Class c = obj.getClass();

// 获取该对象的propertyName成员变量

Field field = c.getDeclaredField(propertyName);

// 取消访问检查

field.setAccessible(true);

// 给对象的成员变量赋值为指定的值

field.set(obj, value);

}

}

package cn.itcast.test;

public class ToolDemo {

public static void main(String[] args) throws NoSuchFieldException,

SecurityException, IllegalArgumentException, IllegalAccessException {

Person p = new Person();Tool t = new Tool();

t.setProperty(p, "name", "林青霞");

t.setProperty(p, "age", 27);

System.out.println(p);

System.out.println("-----------");Dog d = new Dog()

t.setProperty(d, "sex", ‘男‘);t.setProperty(d, "price", 12.34f);System.out.println(d);

}

}class Dog {

char sex;

float price;

@Override

public String toString() {

return sex + "---" + price;

}

}

class Person {

private String name;

public int age;

@Override

public String toString() {

return name + "---" + age;

}

}

  1. 模式一般的方法

简单工厂模式和工厂方法模式(接口)模版设计模式(抽象类)

装饰设计模式(IO流)单例设计模式(多线程)适配器模式(GUI)

  1. 抽象类不能自己创建对象,假如要将创建对象,我们可以让子类赋值和父类(多态)代替。
  2. 枚举的格式及方法和注意事项。

格式是:只有枚举项的枚举类

public enum 枚举类名 {

枚举项1,枚举项2,枚举项3…;

}

注意事项

定义枚举类要用关键字enum所有枚举类都是Enum的子类

枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其他的东西,这个分号就不能省略。建议不要省略

枚举类可以有构造器,但必须是private的,它默认的也是private的。枚举项的用法比较特殊:枚举(“”);

枚举类也可以有抽象方法,但是枚举项必须重写该方法

枚举在switch语句中的使用

int compareTo(E o)         String name()   int ordinal()

String toString()        <T> T valueOf(Class<T> type,String name)

values()

此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便

  1. Jdk7的一些新特性

jDK7开始,终于可以用二进制来表示整数(byte,short,int和long)。使用二进制字面量的好处是,可以使代码更容易被理解。语法非常简单,只要在二进制数值前面加 0b或者0B

举例:  int x = 0b110110

(是零不是欧)

为了增强对数值的阅读性,如我们经常把数据用逗号分隔一样。JDK7提供了_对数据分隔。

举例:

int x = 100_1000;

注意事项:

不能出现在进制标识和数值之间

不能出现在数值开头和结尾

不能出现在小数点旁边

格式:

try(必须是java.lang.AutoCloseable的子类对象){…}

好处:

资源自动释放,不需要close()了

把需要关闭资源的部分都定义在这里就ok了

主要是流体系的对象是这个接口的子类(看JDK7的API)

package cn.itcast_03;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.util.ArrayList;

public class Demo {

public static void main(String[] args) {

// 二进制字面量

int x = 0b100101;

System.out.println(x);

// 数字字面量可以出现下划线

int y = 1_1123_1000;

// 不能出现在进制标识和数值之间

int z = 0x111_222;

// 不能出现在数值开头和结尾

int a = 0x11_22;

// 不能出现在小数点旁边

double d = 12.3_4;

// switch 语句可以用字符串?自己回顾

// 泛型简化

ArrayList<String> array = new ArrayList<>();

// 异常的多个catch合并

method();

}

private static void method() {

// try-with-resources 语句

// try(必须是java.lang.AutoCloseable的子类对象){…}

try {

FileReader fr = new FileReader("a.txt");

FileWriter fw = new FileWriter("b.txt");

int ch = 0;

while ((ch = fr.read()) != -1) {

fw.write(ch);

}

fw.close();

fr.close();

} catch (IOException e) {

e.printStackTrace();

}

// 改进版的代码

try (FileReader fr = new FileReader("a.txt");

FileWriter fw = new FileWriter("b.txt");) {

int ch = 0;

while ((ch = fr.read()) != -1) {

fw.write(ch);

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

  1. Jdk8的新特性代码

interface Inter

{

//抽象方法

public abstract void show();

//default方法

public default void defaultPrint()

{

System.out.println("defaultPrint 我爱林青霞");

}

//static方法

public static void staticPrint()

{

System.out.println("staticPrint 我爱林青霞");

}

}

//实现类

class InterImpl implements Inter

{

public void show()

{

System.out.println("重写接口中的方法");

}

}

//测试类

public class Demo01

{

public static void main(String[] args)

{

//Inter.defaultPrint();  //非静态方法不能直接使用

Inter.staticPrint();

Inter i = new InterImpl();

i.defaultPrint();

i.show();

}

}

时间: 2024-07-30 10:17:24

JAVA笔记(十五)的相关文章

Java笔记十五.深入理解类和对象(2)

类是对某一类事务的描述,是抽象的.概念上的定义:对象是实际存在的该类事务的个体,因而也称实例.可见,类描述了对象的属性和对象的行为,一个类可以对应多个对象. 一.对象 1.new关键字 在Java编程中,我们通过使用new关键字和想要创建对象的类名来实例化一个类的对象.实例化对象作用,是为对象分配内存,由new操作符根据构造方法决定新建对象分配多大的内存来存储对象.new操作符需要一个参数,就是类的构造方法,构造方法是用于初始化对象的特别方法.new操作符为对象分配内存后将调用类的构造方法确定对

Swift 学习笔记十五:扩展

扩展就是向一个已有的类.结构体或枚举类型添加新功能(functionality).扩展和 Objective-C 中的分类(categories)类似.(不过与Objective-C不同的是,Swift 的扩展没有名字.) Swift 中的扩展可以: 1.添加计算型属性和计算静态属性 2.定义实例方法和类型方法 3.提供新的构造器 4.定义下标 5.定义和使用新的嵌套类型 6.使一个已有类型符合某个协议 一.扩展属性,构造器,方法 class Human{ var name:String? va

laravel3学习笔记(十五)

原作者博客:ieqi.net ==================================================================================================== 异常与日志 在应用中,我们总会遇到各种问题.各种异常,这时,记录异常发生时的状态就很重要,所以异常与日志是有着天然的关系的. 关于异常与日志的配置在文件 application/config/error.php 中. 文件中有四个配置项: 'ignore' => ar

java(第十五章)

第十五章 一.字符串类String 1.String是一个类,位于java.lang包中 2.创建一个字符串对象的2种方式: String 变量名="值"; String 对象名=new String("值"); 3.字符串的常用方法 3.1 字符串长度--length() 3.2 判断值是否相等 equals() 3.3 判断字符串对象地址是否相同 == 3.4 忽略 大小写 判断 equalsIgnoreCase() 3.5 大小写转换 toLowerCase(

Java读书笔记十五(Java中的内部类)

前言 Java从JDK1.1的时候,就开始引入内部类的概念了,那么小编也通过这篇博客来分享一下Java中有关内部类的一些特性. 什么是内部类? 在很多情况下,类被定义成一个独立的程序单元,但是有时候也会把一个类放在另一个类的内部定义,这个定义在其他类内部的类就称为内部类. 从语法上来看的话,定义内部类和定义外部类的语法大致相同,内部类除了需要定义在其他类里面之外,还存在如下两点区别. 1.内部类比外部类多使用三个修饰符:private--protected.static--外部类不可以使用这三个

Java基础学习笔记十五 集合、迭代器、泛型

Collection 集合,集合是java中提供的一种容器,可以用来存储多个数据. 在前面的学习中,我们知道数据多了,可以使用数组存放或者使用ArrayList集合进行存放数据.那么,集合和数组既然都是容器,它们有啥区别呢? 数组的长度是固定的.集合的长度是可变的. 集合中存储的元素必须是引用类型数据 集合继承关系图 ArrayList的继承关系: 查看ArrayList类发现它继承了抽象类AbstractList同时实现接口List,而List接口又继承了Collection接口.Collec

【DAY15】Java第十五天I/O学习笔记

RandomAccessFile -------------------- 随机访问文件. 1.Object --> java.io.RandomAccessFile 它不流体系中的一员. 2.该对象中封装了字节流,同时还封装了一个缓冲区(字节数组),通过内部的指针来操作数组                中的数据. 3.实现接口:DataInput DataOuput 4.seek(int long); 定位下表 5.skipBytes(int bytes); 跳过字节数 6.getFileP

Java之十五 JDBC编程

有了JDBC,向各种关系数据发送SQL语句就是一件很容易的事.换言之,有了JDBCAPI,就不必为访问Sybase数据库专门写一个程序,为访问Oracle数据库又专门写一个程序,或为访问Informix数据库又编写另一个程序等等,程序员只需用JDBCAPI写一个程序就够了,它可向相应数据库发送SQL调用.同时,将Java语言和JDBC结合起来使程序员不必为不同的平台编写不同的应用程序,只须写一遍程序就可以让它在任何平台上运行,这也是Java语言"编写一次,处处运行"的优势. Java数

Java笔记十四.深入理解类和对象(1)

Java是一种完全面向对象的编程语言(C是面向过程).所谓面向对象编程(OOP),即是一种编程风格,它通过给程序中加入扩展语句,把函数"封装"进编程所必需的"对象"中.OOP 达到了软件工程的三个主要目标:重用性.灵活性和扩展性.其实,面向对象就是把一切东西看成一个个对象,比如人,车,面包,等等,然后把这些对象拥有的属性变量,比如年龄,民族,工作地点,变质期,寿命,还有操作这些属性变量的函数(方法)打包成一个类来表示,这个类的一个抽象就是一个对象.在Java程序中,

西门子PLC学习笔记十五-(数据块及数据访问方式)

一.数据块 数据块是在S7 CPU的存储器中定义的,用户可以定义多了数据块,但是CPU对数据块数量及数据总量是有限制的. 数据块与临时数据不同,当逻辑块执行结束或数据块关闭,数据块中的数据是会保留住的. 数据块分共享数据块.背景数据块.用户自定义数据块,下面分别介绍. 1.共享数据块(全局数据块) 其用于存储全局数据,所有逻辑块(OB.FC.FB)都可以访问共享数据块中的数据. 2.背景数据块(私有存储区) 其用做功能块(FB)的"存储器".FB的参数和静态变量安排在它的背景数据块中.