java易错题锦集系列五

news/2024/4/24 6:38:04/文章来源:https://blog.csdn.net/weixin_44154094/article/details/129257898

接口中不能有构造方法,抽象类中可以有。抽象类中构造方法作用:初始化抽象类的成员;为继承它的子类使用

定义在同一个包(package)内的类是可以不经过import而直接相互使用

final修饰的方法可以被重载 但不能被重写

从设计层面来说,抽象类是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。

  • 进入DEAD的线程,它还可以恢复,GC不会回收

静态变量

下列代码输出什么

class HasStatic{private static int x = 100;public static void main(String args[ ]){HasStatic hs1 = new HasStatic();hs1.x++;HasStatic hs2 = new HasStatic();hs2.x++;hs1=new HasStatic();hs1.x++;HasStatic.x--;System.out.println( "x=" +x);}
}

答案:102

判断:

  • 在java中,我们可以用违例(Exception)来抛出一些并非错误的消息,但这样比直接从函数返回一个结果要更大的系统开销。

可以用违例(Exception)来抛出一些并非错误的消息,可以,并非错误的消息。比如我自定义一个异常,若一个变量大于10就抛出一个异常,这样就对应了B选项说的情况,我用抛出异常说明这个变量大于10,而不是用一个函数体(函数体内判断是否大于10,然后返回true或false)判断,因为函数调用是入栈出栈,栈是在寄存器之下的速度最快,且占的空间少,而自定义异常是存在堆中,肯定异常的内存开销大!所以B对。

javac

构造器

易错:超易错,

下面代码将在哪一处报错:

public class MyClass {long var;public void MyClass(long param) { var = param; }//(1)public static void main(String[] args) {MyClass a, b;a =new MyClass();//(2)b =new MyClass(5);//(3)}
}

答案:3)

构造方法就是:public 类名, 没有方法修饰符
所以 (1)  处就是一个普通方法
所以该类没有带参数构造方法 ,编译报错

易错2:

下面代码将输出什么

public class Test {public int aMethod(){static int i = 0;i++;return i;}
public static void main(String args[]){Test test = new Test();test.aMethod();int j = test.aMethod();System.out.println(j);}
}

答案:报错
静态变量只能在类主体中定义,不能在方法中定义


  • 子类不但可以继承父类的无参构造函数,也可以继承父类的有参构造函数。
    答案:x
构造函数不能被继承,构造方法只能被显式或隐式的调用。如果说有参构造可以被继承,那么在子类中有参构造就可以被重写;那么就无法通过父类的有参构造创建对象了;所以有参构造不能被继承。1.构造函数不能继承,只是调用而已;
2.若父类没有无参构造函数,则创建子类时,不能编译;除非在构造函数代码体中第一行,必须是第一行显示调用父类的有参构造函数;
3.若父类中没有任何构造函数,则系统会默认有一个无参构造函数如果父类中只定义了有参数构造方法,jvm就不会隐式为父类创建无参数构造,那么,你在创建子类继承父类时,你的子类就必须调用父类中任何一个有参数构造进行初始化才行,如果,在你的子类中仅仅写个无参数构造,那么编译不通过

访问权限

  • 访问权限控制从最大权限到最小权限依次为:public、 包访问权限、protected和private 。
    答案:错
    public、protected、 包访问权限和private 。

下面代码运行结果是什么

public class Arraytest{int a[] = new int[6];public static void main ( String arg[] ) {System.out.println ( a[0] );}
}

答案: 编译错误
在static方法中是不能访问非静态变量 a 的,需要将 a 声明为static,答案才会是 0 ,否则是编译出错

匿名内部类

匿名内部类可以看这里,

  • 匿名内部类不可以定义构造器

答案:✓

匿名内部类的创建格式为: new 父类构造器(参数列表)|实现接口(){//匿名内部类的类体实现}
使用匿名内部类时,必须继承一个类或实现一个接口
匿名内部类由于没有名字,因此不能定义构造函数
匿名内部类中不能含有静态成员变量和静态方法

Byte

下面代码输出什么:

public class Test2
{public void add(Byte b){b = b++;}public void test(){Byte a = 127;Byte b = 127;add(++a);System.out.print(a + " ");add(b);System.out.print(b + "");}
}

答案:-128 127
解析:

包装类的值是final修饰不可变的,无论是++b还是b++都创建了一个新对象,那么作为参数传递时,形参和实参不会指向一个地址。也就是说,即使add() 方法中不是b = b++;这样没有意义的代码,传入参数的值也不会改变。byte类型取值范围为-128~127,在a变量进行++a运算时,会导致a变为-128,这是因为整数在内存中使用的是补码的形式表示,最高位是符号位,0表示正数,1表示负数,加一导致补码进位,符号位变为1.因此,本题正确输出为-128 127

左移右移

>>表示右移,如果该数为正,则高位补0,若为负数,则高位补1;
>>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0运算符“>>”执行算术右移,它使用最高位填充移位后左侧的空位。右移的结果为:每移一位,第一个操作数被2除一次,移动的次数由第二个操作数确定。逻辑右移或叫无符号右移运算符“>>>“只对位进行操作,没有算术含义,它用0填充左侧的空位。算术右移不改变原数的符号,而逻辑右移不能保证这点。移位运算符约简其右侧的操作数,当左侧操作数是int类型时,右侧以32取模;当左侧是long类型时,右侧以64取模。
>> 右移 高位补符号位
>>> 右移 高位补0
~~~ 逻辑左移时,最高位丢失,最低位补0;~~~
逻辑右移时,最高位补0,最低位丢失;
算术左移时,依次左移一位,尾部补0,最高的符号位保持不变。
算术右移时,依次右移一位,尾部丢失,符号位右移后,原位置上复制一个符号位;
循环左移时,将最高位重新放置最低位
循环右移时,将最低位重新放置最高位
例如:
1010100010101
~~逻辑左移一位结果为 0101000101010~~
逻辑右移一位结果为 0101010001010
算术左移一位结果为 1101000101010
算术右移一位结果为 1101010001010
循环左移一位结果为 0101000101011
循环右移一位结果为 1101010001010

总结的比较好的

java跨平台运行

write once,run everywhere 指的是编译后的字节码可以跨平台执行,也就是class文件,而不是Java源文件

is-a has-a like-a

is-a:继承关系 has-a:从属关系 like-a:组合关系
抽象类表示的是 is-a 关系;
接口表示的是 like-a 关系;

易错

package algorithms.com.guan.javajicu; 
public class Inc { public static void main(String[] args) { Inc inc = new Inc(); int i = 0; inc.fermin(i); i= i ++; System.out.println(i);} void fermin(int i){ i++; } 
}

答案:0

第二弹

下面代码编译会报错吗?

public class Person{static int arr[] = new int[5];public static void main(String a[]){System.out.println(arr[0]);}}

答案:不会,初始化的时候会赋初始值0,5个0

接口

接口中只能有静态的不能被修改的成员,也就是必须是static final的

如果是Java 7以及以前的版本,那么接口中可以包含的内容有:1. 常量;2. 抽象方法
如果是Java 8,还可以额外包含有:3. 默认方法;4. 静态方法
如果是Java 9,还可以额外包含有:5. 私有方法

4.JAVA中,假设A有构造方法A(int a),则在类A的其他构造方法中调用该构造方法和语句格式应该为()Athis.A(x)
Bthis(x)
Csuper(x)
DA(x)

解析:


答案:B
this的作用其中一个就是在一个构造方法中调用另一个构造方法,格式为this(参数); super是调用父类的方法 比如super.start();
A(a)这种形式是在new一个类时使用。

基类 导出类

基类就是父类,也叫超类。导出类就是子类,也叫派生类。

threadLocal

关于ThreadLocal类 以下说法正确的是
A.ThreadLocal继承自Thread
B.ThreadLocal实现了Runnable接口
C.ThreadLocal重要作用在于多线程间的数据共享
D.ThreadLocal是采用哈希表的方式来为每个线程都提供一个变量的副本
E.ThreadLocal保证各个线程间数据安全,每个线程的数据不会被另外线程访问和破坏

答案:de
1、ThreadLocal的类声明: public class ThreadLocal 可以看出ThreadLocal并没有继承自Thread,也没有实现Runnable接口。所以AB都不对。 2、ThreadLocal类为每一个线程都维护了自己独有的变量拷贝。每个线程都拥有了自己独立的一个变量。 所以ThreadLocal重要作用并不在于多线程间的数据共享,而是数据的独立,C选项错。 由于每个线程在访问该变量时,读取和修改的,都是自己独有的那一份变量拷贝,不会被其他线程访问, 变量被彻底封闭在每个访问的线程中。所以E对。 3、ThreadLocal中定义了一个哈希表用于为每个线程都提供一个变量的副本: 所以D对。

servlet生命周期

Servlet生命周期分成3个阶段:
1)初始化阶段:调用init方法
2)响应客户请求:调用service
3)终止:调用destory方法

初始化阶段:在下列时刻servlet容器装载servlet

1 servlet容器启动时,自动装载某些servlet
2 在servlet容器启动后,客户首次向servlet发送请求
3 servlet类文件被更新之后,重新装载servlet

Servlet被装载之后,servlet容器创建一个servlet’对象并调用servlet的init方法,在servlet生命周期内,init方法只能被调用一次。servlet工作原理:客户端发起一个请求,servlet调用service方法时请求进行响应,service对请求的方式进行了匹配,选择调用dopost或者doget等这些方法,然后进入对应方法中调用逻辑层的方法,实现对客户的响应。

响应客户请求:对于用户到达servlet的请求,servlet容器会创建特定于该请求的servletrequest和servletresponse对象,然后调用servlet的service方法,service方法从servletrequest对象中获取客户请求的信息,处理该请求,并且通过servletresponse对象向客户端返回响应信息。

终止:当web应用终止或者servlet容器终止或servlet容器重新装载servlet新实例时,servlet容器会调用servlet对象的destory方法,在destory方法中可以释放servlet占用的资源

易错题

下面输出什么:

Boolean flag = false;
if (flag = true)
{System.out.println("true");
}
else
{System.out.println("false");
}

答案: true
看清,flag = true 不是 ==

第二

下面哪段代码插入进来不会报错

interface Com{int M=200;int f();
}
class ImpCom implements Com{【代码】
}>
A. public int f(){return 100+M;}
B. int f(){return 100;}
C. public double f(){return 2.6;}
D. public abstract int f();

答案:A
B选项没有修饰符,不知道是public default 还是什么
1、必须实现接口中所有的方法。
在实现类中实现接口时,方法的名字、返回值类型、参数的个数及类型必须与接口中的完全一致,并且必须实现接口中的所有方法。

2、接口实现类相当于子类,子类的访问权限是不能比父类小的。
接口中所有方法默认都是public,至于为什么要是public,原因在于如果不是public,那么只能在同个包下被实现,可访问权限就降低很多了,那么在实现类中,实现的类相当于子类,子类的访问权限是不能比父类小的,而在java中一个类如果没有权限的修饰符,默认是friendly(同一个包内的其它类才可访问),所以在实现类中一定要写public

类型转换

语句1,2,3,4哪几个是错的?

byte b1=1,b2=2,b3,b6,b8;
final byte b4=4,b5=6,b7;
b3=(b1+b2);  /*语句1*/
b6=b4+b5;    /*语句2*/
b8=(b1+b4);  /*语句3*/
b7=(b2+b5);  /*语句4*/
System.out.println(b3+b6);

答案: 1,3,4

1、所有的byte,short,char型的值将被提升为int型;
2、如果有一个操作数是long型,计算结果是long型;
3、如果有一个操作数是float型,计算结果是float型;
4、如果有一个操作数是double型,计算结果是double型;
5、被fianl修饰的变量不会自动改变类型,当2final修饰相操作时,结果会根据左边变量的类型而转化。
--------------解析--------------
语句1错误:b3=(b1+b2);自动转为int,所以正确写法为b3=(byte)(b1+b2);或者将b3定义为int;
语句2正确:b6=b4+b5;b4、b5为final类型,不会自动提升,所以和的类型视左边变量类型而定,即b6可以是任意数值类型;
语句3错误:b8=(b1+b4);虽然b4不会自动提升,但b1仍会自动提升,所以结果需要强转,b8=(byte)(b1+b4);
语句4错误:b7=(b2+b5); 同上。同时注意b7是final修饰,即只可赋值一次,便不可再改变。

反射

getDeclaredField:查找该Class所有声明属性(静态/非静态),但是他不会去找实现的接口/父类的属性
getField:只查找该类public类型的属性,如果找不到则往上找他的接口、父类,依次往上,直到找到或者已经没有接口/父类

public Object getName1() throws NoSuchFieldException, IllegalAccessException {return User.class.getDeclaredField("name").get(null);}public Object getName2() throws NoSuchFieldException, IllegalAccessException {return User.class.getField("name").get(null);}public Object getName3() throws NoSuchFieldException, IllegalAccessException {User user=new User(); return user.getClass().getField("name").get(user);}public Object getName4() throws NoSuchFieldException, IllegalAccessException {User user=new User(); return user. getClass().getDeclaredField("name").get (user);}

get方法是获得user对象下前面指定好的属性的值,而获取static属性时get()括号里的对象可以写成null

多态

下面代码输出什么?

class A {public int func1(int a, int b) {return a - b;}
}
class B extends A {public int func1(int a, int b) {return a + b;}
}
public class ChildClass {public static void main(String[] args) {A a = new B();B b = new B();System.out.println("Result=" + a.func1(100, 50));System.out.println("Result=" + b.func1(100, 50));}
}

答案:两个150
多态绑定机制:
实例方法与引用变量所引用的对象的方法绑定;
静态方法与引用变量所声明的类型的方法绑定;
成员变量(实例变量、静态变量)与引用变量所声明的类型的成员变量绑定。
在这道题目中,由于都是实例方法,所以与所引用的对象的方法绑定。(new 后跟引用对象)

涉及转型的题目,分为向上或者向下转型。 关键的来了,不论向上或者向下转型,都是一句话,“编译看左边,运行看右边”。也就是编译时候,会看左边引用类型是否能正确编译通过,运行的时候是调用右边的对象的方法。A a=new B();这是向上转型。B b=(B)a;这是向下转型。但是,A a =new A();B b= (B)a;此时会报错。 就本题来说,编译时候会发现左边满足条件所以编译通过,运行时候又会调用右边也就是 class B 的方法,所以答案都是150。

下面关于变量及其范围的陈述哪些是不正确的()
A。实例变量是类的成员变量
B。实例变量用关键字static声明
C。在方法中定义的局部变量在该方法被执行时创建
D。局部变量在使用前必须被初始化

答案:BC
解析:
类的成员变量包括实例变量和类变量(静态变量),成员方法包括实例方法和类方法(静态方法)
C.方法中的局部变量在方法被调用加载时开始入栈时创建,方法入栈创建栈帧包括局部变量表操作数栈,局部变量表存放局部变量,并非在执行该方法时被创建,C错误
D.局部变量被使用前必须初始化,否则程序报错。D正确

finally

下面输出什么

public class Demo {public static String sRet = "";public static void func(int i){try{if (i%2==0){throw new Exception();}}catch (Exception e){sRet += "0";return;} finally{sRet += "1";}sRet += "2";}public static void main(String[] args){func(1);func(2);System.out.println(sRet);}
}

答案:1201
解答:
第一步,func(1),if条件不成立,不抛出异常,catch不运行,final运行,拼串得到“1”,程序继续往下走,拼串得到“12”。 第二步,fun(2),if条件成立,抛出异常,catch捕获异常,运行catch里面代码,拼串得到“120”,虽然有return,但是不管出不出异常,final里代码必须执行,执行final,拼串得到“1201”,然后return结束。所以最终结果“1201”

下列流当中,属于处理流的是:()     
A.FilelnputStream
B.lnputStream
C.DatalnputStream
D.BufferedlnputStream
按照流是否直接与特定的地方(如磁盘、内存、设备等)相连,分为节点流和处理流两类。节点流:可以从或向一个特定的地方(节点)读写数据。如FileReader.
处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
JAVA常用的节点流:文 件 FileInputStream FileOutputStrean FileReader FileWriter 文件进行处理的节点流。
字符串 StringReader StringWriter 对字符串进行处理的节点流。
数 组 ByteArrayInputStream ByteArrayOutputStreamCharArrayReader CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)。
管 道 PipedInputStream PipedOutputStream PipedReaderPipedWriter对管道进行处理的节点流。常用处理流(关闭处理流使用关闭里面的节点流)缓冲流:BufferedInputStrean BufferedOutputStream BufferedReader BufferedWriter  增加缓冲功能,避免频繁读写硬盘。
转换流:InputStreamReader OutputStreamReader 实现字节流和字符流之间的转换。
数据流 DataInputStream DataOutputStream  等-提供将基础数据类型写入到文件中,或者读取出来.
流的关闭顺序
一般情况下是:先打开的后关闭,后打开的先关闭
另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b。例如,处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法。

servlet体系结构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_75518.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线性插值基本原理推导

线性插值基本原理1. 为什么使用线性插值?2. 单线性插值2.1 单线性插值推导3.多线性插值3.1 多线性插值推导注意事项3.2 多线性插值推导3.3 插入坐标越远权重越大1. 为什么使用线性插值? 在深度学习对图片进行上采样和下采样的时候会应用到线性插值 对图…

TypeScript 使用 ES6 解构骚操作

TypeScript 使用 ES6 解构骚操作 文章目录TypeScript 使用 ES6 解构骚操作一、TypeScript 对象解构二、TypeScript 函数参数解构四、参考资料💘五、推荐博文🍗一、TypeScript 对象解构 我们都知道 ES6 的数据解构功能很强大,一行命令就能够声…

TypeScript 常用知识

「 推荐一个学习 ts 基础的专栏,满满的干货:typeScript 」 1、为什么推荐使用 TypeScript 【】ts 是 js 的超集,包含 js 的所有元素 【】ts 通过对代码进行类型检查,可以帮助我们避免在编写 js 时经常遇到令人痛苦的错误 【】强…

云端IDE系列教程7:解决 WeTTY 在 Ubuntu 非 root 用户不能运行的问题

原文作者:行云创新技术总监 邓冰寒 概述 上一期在使用官方容器镜像快速成功地在 TitanIDE 运行起来了 WeTTY,但是不适合开发人员使用,而我自己编译构建出来的容器镜像无法直接运行指定的应用(/bin/bash 或 /bin/zsh)&…

GO中sync 包的 RWMutex 读写互斥锁

文章目录背景RWMutex 简介代码验证多个协程请求读锁 RLock() 和 RLock()读写交错 RLock() 和 Lock()写入的时候读取读取的时候写入请求多个写Lock() 和 Lock()背景 Mutex 互斥锁是严格锁定读和写,如果我们需要单独对读或者写添加锁需要使用 sync包的RWMutex 针对读…

PHP使用chilkat入门教程

前言: 我们需要先确认自己的版本,在PHP中,可以利用phpinfo()函数来查看php是ts版本还是nts版本,该方法可以展示出当前phpinfo信息,若“Thread Safety”项的信息是“enabled”,一般来说就表示ts版本&#xf…

备战英语6级——记录复习进度

开始记录—— 学习:如何记录笔记? 1:首先我认为:电脑打字比较适合我! 2:先记笔记,再“填笔记”! 记笔记就是一个框架,记录一个大概的东西。后面需要在笔记中&#xff0…

实例10:四足机器人运动学逆解可视化与实践

实例10: 四足机器人运动学逆解单腿可视化 实验目的 了解逆运动学的有无解、有无多解情况。了解运动学逆解的求解。熟悉逆运动学中求解的几何法和代数法。熟悉单腿舵机的简单校准。掌握可视化逆向运动学计算结果的方法。 实验要求 拼装一条mini pupper的腿部。运…

Qt 事件机制

【1】事件 事件是可以被控件识别的操作。如按下确定按钮、选择某个单选按钮或复选框。 每种控件有自己可识别的事件,如窗体的加载、单击、双击等事件,编辑框(文本框)的文本改变事件等等。 事件就是用户对窗口上各种组件的操作。…

LibAFL的安装及基本使用

本教程安装LibAFL使用的是Ubuntu 22.04 操作系统 1. 安装 1.1 Rust 安装 Rust的安装,参照Rust官网:https://www.rust-lang.org/tools/install curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh1.2 LLVM安装 直接apt安装,安…

表格形式的Sarsa与Q_learning算法

环境如下: 这是一个简单的环境,绿色方块代表终点,白色方块代表可行点,灰色方块代表陷阱 用Sarsa算法和Q_learning算法训练得到value表格 代码如下: (jupyter notebook上的代码,所以顺序看起来有点儿奇怪) …

Java8 新特性强大的Stream API

一、Stream API 说明 Java8中有两大最为重要的改变。第一个是 Lambda 表达式;另外一个则是 Stream API。 Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。这是目前为止对Java类库最好的补充,因为Stream API可以极大提供Ja…

【博学谷学习记录】超强总结,用心分享丨人工智能 特征工程 特征变换 分箱学习总结

目录概念分箱的作用等频分箱等距分箱*卡方分箱公式例子概念 特征构造的过程中,对特征做分箱处理时必不可少的过程分箱就是将连续变量离散化,合并成较少的状态 分箱的作用 离散特征的增加和减少都很容易,易于模型的快速迭代;稀疏…

基于自定义训练函数的BP神经网络回归分析

目录 背影 BP神经网络的原理 BP神经网络的定义 BP神经网络的神经元 BP神经网络的激活函数 BP神经网络的传递函数 基于自定义训练函数的BP神经网络回归分析 背影 BP神经网络是一种成熟的神经网络,拥有很多训练函数,传递函数,激活函数&#x…

数学小课堂:无穷小(用动态和极限的眼光看世界)

文章目录 引言I 极限1.1 柯西对极限的认知1.2 极限准确的定义1.3 数列极限的定义1.4 函数极限的定义1.5 无穷小(特殊的极限)1.6 定量和逆向思维1.7 认知升级的过程引言 身处于渐变世界的人类,难以理解瞬间突变。 老师的作用,就是用大白话,把数学语言所写的知识,翻译成大…

腾讯安全与锐捷网络战略合作,威胁情报能力“被集成”

2月28日,腾讯安全和锐捷网络在北京联合举办“威胁情报”战略合作发布会。双方发布了一款集成了腾讯安全威胁情报的新一代防火墙,并举办战略合作签约仪式。会上,锐捷网络安全产品事业部总经理项小升、腾讯安全总经理陈龙代表双方签署战略合作协…

Python可视化界面编程入门

Python可视化界面编程入门具体实现代码如所示: (1)普通可视化界面编程代码入门: import sys from PyQt5.QtWidgets import QWidget,QApplication #导入两个类来进行程序界面编程if __name__"__main__":#创建一个Appl…

k8s学习之路 | Day17 k8s 工作负载

文章目录工作负载的定义工作负载资源分类工作负载的定义 官方参考链接:https://kubernetes.io/docs/concepts/workloads/ A workload is an application running on Kubernetes. Whether your workload is a single component or several that work together, on K…

《C++ Primer Plus》(第6版)第6章编程练习

《C Primer Plus》(第6版)第6章编程练习《C Primer Plus》(第6版)第6章编程练习1. 大小写转换2. 平均值3. 菜单4. 成员5. 收入所得税6. 捐款7. 统计单词8. 统计文件字符数9. 重写编程练习6《C Primer Plus》(第6版&…

创建对象的方式和对属性的操作

javaScript支持多种编程范式,包括函数式编程和面向对象编程,javaScript的对象被设计成一组属性的无序集合,由key和value组成。 创建对象的两种方式 早期使用创建对象方式最多的是使用Object类,使用new关键字来创建一个对象&…