Java基础题目汇总

一、集合框架

1. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别

答:Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等
     equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值

2. 数组和集合的使用区别

①、数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型)

②、集合可以存储和操作数目不固定的一组数据

③、数据重复问题,Set可以解决数据重复问题

3. 什么是iterator?

为了方便处理集合中的元素,Java中出现了一个对象,该对象提供了一些方法专门处理集合中的元素,例如删除和获取集合中的元素,该对象就叫做迭代器iterator。Iterator接口提供了很多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代器实例的迭代方法。迭代器可以在迭代的过程中删除底层集合的元素。

4. HashMap和HashTable区别?

  1. 作者不同
  2. 产生时间不同,HashTable早于HashMap
  3. 继承父类不同,HashMap继承自AbstractMap,HashTable继承自Dictionary(已废弃)
  4. 线程安全不同,HashTable线程安全。
  5. 对外提供接口不同,Hashtable比HashMap多提供了elments() 和contains() 两个方法。
  6. 对Null key 和Null value的支持不同,HashTable不允许键值为null
  7. 遍历方式的内部实现上不同
  8. 初始容量大小和每次扩充容量大小的不同
  9. 计算hash值的方法不同

详情点击

5. HashMap 与 ConcurrentHashMap区别?

HashMap线程不安全,ConcurrentHashMap线程安全。

HashMap底层数据结构是数组+链表(JDK1.8之前);JDK1.8之后是数组+链表+红黑树。当链表中的元素个数达到8之后,链表查询速度不如红黑树,链表会转为红黑树,红黑树查询速度快。

HashMap初始数组大小是16(默认),当出现扩容时,以0.75*数组大小的方式进行扩容。

ConcurrentHashMap是采用分段锁来实现Segment+HashEntry(JDK1.8之前),Segment数组大小默认是16,2的N次方;JDK 1.8 之后,采用 Node + CAS + Synchronized来保证并发安全进行实现。

6. Map最优遍历方式?

map有三种遍历方式:

  1. map.value();
  2. map.keySet();
  3. map.entrySet();

其中,最优遍历是entrySet(),效率最高。

7. 怎么确保一个集合不被修改?

Collections的unmodiableList(); unmodiableMap(); unmodiableSet();

8. 哪些集合类是线程安全的?

Vector:就比ArrayList多了个同步化机制(线程安全)

HashTable:就比HashMap多了个线程安全

ConcurrentHashMap:是一种高效但是线程安全的集合

9. 简述一下HashMap与 HashTable的底层数据结构?

HashMap:数组+链表

HashTable:和HashMap相似,其基本内部数据结构是一个Entry数组

10. poll()和remove()区别?offer()和add()区别?peek()和element()区别?

  • poll()和remove()都将移除并且返回对头,但是在poll()在队列为空时返回null,而remove()会抛出NoSuchElementException异常。
  • add()和offer()都是向队列中添加一个元素。但是如果想在一个满的队列中加入一个新元素,调用 add() 方法就会抛出一个 unchecked 异常,而调用 offer() 方法会返回 false。可以据此在程序中进行有效的判断!
  • peek()和element()都将在不移除的情况下返回队头,但是peek()方法在队列为空时返回null,调用element()方法会抛出NoSuchElementException异常。

11、ArrayList和LinkList区别?

ArrayList:基于动态数组,连续内存存储,适合下标访问(随机访问),扩容机制:因为数组长度固定,超出长度存数据时需要新建数组,然后将老数组的数据拷贝到新数组,如果不是尾部插入数据还会涉及到元素的移动(往后复制一份,插入新元素),使用尾插法并指定初始容量可以极大提升性能、甚至超过linkedList(需要创建大量的node对象)

LinkList:基于链表,可以存储在分散的内存中,适合做数据插入及删除操作,不适合查询:需要逐一遍历。

遍历LinkedList必须使用iterator不能使用for循环,因为每次for循环体内通过get(i)取得某一元素时都需要对list重新进行遍历,性能消耗极大。
另外不要试图使用indexOf等返回元素索引,并利用其进行遍历,使用indexlOf对list进行了遍历,当结果为空时会遍历整个列表。

 




二、异常

1. 常见的RuntimeException有哪些?

答:常见的运行时异常有如下这些ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException

2. errorexception有什么区别

答:error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况
     exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况

3. 空指针异常

①、指针,就是java中的对象的引用。比如String s  这个s就是指针;

②、空指针,就是指针的内容为空,比如上面那个s,如果令它指向null,就是空指针;

③、空指针异常,就是一个指针是空指针,还要去操作它,既然它指向的是空对象,他就不能使用这个对象的方法。比如上面的s假如为null,还要使用s的方法,就会产生空指针异常

4. 平时怎么处理Java异常

try-catch-finally

  • try 块负责监控可能出现异常的代码
  • catch 块负责捕获可能出现的异常,并进行处理
  • finally 块负责清理各种资源,不管是否出现异常都会执行
  • 其中 try 块是必须的,catch 和 finally 至少存在一个标准异常处理流程

5. 什么是fail-fast

fail-fast 机制是 Java 集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生 fail-fast 事件。

例如:当某一个线程 A 通过 iterator 去遍历某集合的过程中,若该集合的内容被其他线程所改变了,那么线程 A 访问集合时,就会抛出 ConcurrentModificationException 异常,产生 fail-fast 事件。这里的操作主要是指 add、remove 和 clear,对集合元素个数进行修改。

解决办法:建议使用“java.util.concurrent 包下的类”去取代“java.util 包下的类”。

可以这么理解:在遍历之前,把 modCount 记下来 expectModCount,后面 expectModCount 去和 modCount 进行比较,如果不相等了,证明已并发了,被修改了,于是抛出ConcurrentModificationException 异常。

三、基本数据类型和封装类

1. short s = 1, s=s+1错误是什么?   short s=1,s+=1的错误是?

 short s=1;s=s+1的错误是会失去精度,由于1是int类型,s=s+1返回的是int类型,int类型赋值给short就会数据类型转换错误。要强制类型转换。s+=1没有错误。s+=1就是s=(Short)s+1;

2. 说出下面程序的问题。

  byte  b1=1;

  byte  b2=2;

  byte  b3=1+2;

  byte  b4=b1+b2;

byte  b4=b1+b2;有问题,b1和b2是变量,变量的值是不确定的可以变化的,在编译的时候,编译器javac不确定b1+b2的结果是什么,因此会将结果以int类型进行处理,所以int不能赋值给byte,编译失败;

b3=1+2;没有问题,1和2为常量,在编译的时候,编译器已经确定了1+2的结果没有超过byte的取值范围。可以赋值给b3,所以b3=1+2正确。

2. Integer和int的区别?

①Integer是int的包装类,int是Java的基本数据类型;

②Integer默认值是null,int是0;

③Integer需要实例化后才能使用,int不需要;

④Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值。

3. Integer和int哪个占用内存多?

答:一样多。两个都是4字节

4. 自动装箱与自动拆箱

  装箱:基本类型转换为包装类型,例如:Integer i = 1,其实是  Integer i = Integer.valueOf(i);

  拆箱:包装类型转换为基本类型,例如:int x = i ,其实是 int x = i.intValue(); 就是包装器类型.xxxValue()。

  补充:基本类型和包装类型用==比较时,包装类型会自动拆箱为基本类型,所以实际就是两个基本类型在比较。

5. replace和replaceAll区别?

相同点:都是全部替换,即把源字符串中的某一字符或字符串全部换成指定的字符或字符串;

不同点:replaceAll支持正则表达式,因此会对参数进行解析(两个参数均是),如replaceAll("\\d", "*"),而replace则不会,replace("\\d","*")就是替换"\\d"的字符串,而不会解析为正则。

  另外还有一个不同点:“\”在java中是一个转义字符,所以需要用两个代表一个。例如System.out.println( "\\" ) ;只打印出一个"\"。但是“\”也是正则表达式中的转义字符,需要用两个代表一个。所以:\\\\被java转换成\\,\\又被正则表达式转换成\,因此用replaceAll替换“\”为"\\",就要用replaceAll("\\\\","\\\\\\\\"),而replace则replace("\\","\\\\")。

如果只想替换第一次出现的,可以使用replaceFirst(),这个方法也是基于规则表达式的替换,但与replaceAll()不同的是,只替换第一次出现的字符串。

6. 操作字符串都有哪些类

  String:String类的方法都是返回 new String。对String的任何修改都不影响到原对象,对字符串的修改操作都会生成新的对象所以效率低

  StringBuffer:对字符串的操作方法都加了synchronize,保证线程安全

  StringBuilder:相比StringBuffer效率高,不保证线程安全。如果对某个字符串频繁的修改操作,不推荐使用String去操作

7. 各种类型数组元素的默认值

  • int类型定义的数组,初始化默认是0
  • char类型定义的数组,默认值是0对应的字符
  • double类型定义的数组,默认值是0.0
  • float类型定义的数组,默认值是0.0
  • String(引用)类型定义的数组,默认值是null

四、线程

1. 如何编写多线程代码?几种方式?有什么区别?

连接跳转

2. sleep()和wait()的区别?

①、sleep()方法是Thread类的静态方法,单线程;wait()是Object超(父)类的成员方法。

②、sleep()没有释放锁;wait()释放了锁 。sleep导致了线程暂停执行指定时间,让出CPU该其他线程。但是它的监控状态依然保持着。当指定的时间到了又会自动恢复运行状态。

③、sleep()需要进行异常处理,try catch;而wait方法不需要

④、sleep()可以在任何地方使用,而wait()只能在同步方法和同步代码块使用

3. 什么是线程池?在什么情况下使用线程池?优点是?

线程池:Java用来管理线程的池子,限制线程的数量。

什么情况下使用:当程序并发数量很多,并且每个线程都是执行一个时间很短的任务就结束了,那么需要频繁的创建销毁一些相同的线程时,可以使用线程池来管理。

优点:

  1. 避免线程的创建和销毁带来的性能开销。
  2. 避免大量的线程间因互相抢占系统资源导致的阻塞现象。
  3. 能够对线程进行简单的管理并提供定时执行、间隔执行等功能。

4. 如何让一个线程进入阻塞状态?又如何唤醒?

① 同步阻塞:等待锁的释放。

② 等待阻塞:

1)使用Thread.sleep造成的阻塞:时间结束后自动进入RUNNABLE状态
2)使用Thread.wait造成的阻塞:使用Thread.notify或者Thread.notifyAll唤醒
3)使用Thread.join造成的阻塞:等待上一个线程执行完后自动进入RUNNABLE状态

4)使用Thread.suspend造成的阻塞:使用Thread.resum唤醒
5)使用LockSupport.park造成的阻塞:使用LockSupport.unpark唤醒
6)使用LockSupport.parkNanos造成的阻塞:指定时间结束后,自动唤醒
7)使用LockSupport.parkUntil造成的阻塞:到达指定的时间,自动唤醒

阻塞详解

5. volatile关键字能否保证线程安全?

单纯使用 volatile 关键字是不能保证线程安全的

  • volatile 只提供了一种弱的同步机制,用来确保将变量的更新操作通知到其他线程
  • volatile 语义是禁用 CPU 缓存,直接从主内存读、写变量。表现为:更新 volatile 变量时,JMM 会把线程对应的本地内存中的共享变量值刷新到主内存中;读 volatile 变量时,JMM 会把线程对应的本地内存设置为无效,直接从主内存中读取共享变量
  • 当把变量声明为 volatile 类型后,JVM 增加内存屏障,禁止 CPU 进行指令重排

更详细的解析跳转

五、面向对象

1. 面向对象的主要特征有哪些?

2. 什么情况下使用抽象类?

3. 继承和接口的区别?

接口:定义一个类需要实现的方法 属性 索引 事件和可能的参数 返回值类型,具体的实现交由相应的类或结构,从而实现多态。

继承:而继承用于在一个现有父类基础上的功能扩展,把几个类中相同的成员提取出来 放在一个父类中,在子类中添加独特的方法,即继承、扩展 。

  1. 修饰符不同,继承(extends)接口(interface)。
  2. 实现类不同,继承只能继承单个父类,实现类可以实现多个接口。
  3. 继承能够获得父类方法的实现,而接口只能获得方法的定义,所以必须获得所有的方法。
  4. 继承中为父类添加方法不影响子类的继承,但在接口中,为父类(接口)添加一个方法定义,必须在子类中添加此方法的实现  。

4. OOP中的组合、聚合、关联有什么区别?

如果两个对象之间彼此有关系,就说他们是彼此关联的。组合和聚合是面向对象中的两种形式的关联。组合是一种比聚合更强力的关联。

如果A对象是由B对象组合成的,则A对象不存在时,B对象一定不存在。

如果A对象是有B对象聚合成的,则A对象不存在时,B也可以单独存在。

5. 创建对象有几种方式?

  • new
  • 反射
  • clone
  • 序列化

6. Object类常用方法的作用?

clone 方法:保护方法,实现对象的浅复制,只有实现了 Cloneable 接口才可以调用该方法,否则抛出CloneNotSupportedException 异常,深拷贝也需要实现 Cloneable,同时其成员变量为引用类型的也需要实现 Cloneable,然后重写 clone 方法。

finalize 方法:该方法和垃圾收集器有关系,判断一个对象是否可以被回收的最后一步就是判断是否重写了此方法。

equals 方法:该方法使用频率非常高。一般 equals 和 == 是不一样的,但是在 Object 中两者是一样的。子类一般都要重写这个方法。

hashCode 方法:该方法用于哈希查找,重写了 equals 方法一般都要重写 hashCode 方法,这个方法在一些具有哈希功能的 Collection 中用到。

一般必须满足  obj1.equals(obj2)==true 。可以推出  obj1.hashCode()==obj2.hashCode() ,但是hashCode 相等不一定就满足 equals。不过为了提高效率,应该尽量使上面两个条件接近等价。

  • JDK 1.6、1.7 默认是返回随机数;
  • JDK 1.8 默认是通过和当前线程有关的一个随机数 + 三个确定值,运用 Marsaglia’s xorshift scheme 随机数算法得到的一个随机数。

wait 方法:配合 synchronized 使用,wait 方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait() 方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。

调用该方法后当前线程进入睡眠状态,直到以下事件发生。

  1. 其他线程调用了该对象的 notify 方法;
  2. 其他线程调用了该对象的 notifyAll 方法;
  3. 其他线程调用了 interrupt 中断该线程;
  4. 时间间隔到了。

此时该线程就可以被调度了,如果是被中断的话就抛出一个 InterruptedException 异常。

notify 方法:配合 synchronized 使用,该方法唤醒在该对象上等待队列中的某个线程(同步队列中的线程是给抢占 CPU 的线程,等待队列中的线程指的是等待唤醒的线程)。

notifyAll 方法:配合 synchronized 使用,该方法唤醒在该对象上等待队列中的所有线程。

7. 获取一个类Class对象的方式有哪些?

搞清楚类对象和实例对象,但都是对象。
第一种:通过类对象的 getClass() 方法获取,细心点的都知道,这个 getClass 是 Object 类里面的方法。

1 User user=new User();
2 //clazz就是一个User的类对象
3 Class<?> clazz=user.getClass();

第二种:通过类的静态成员表示,每个类都有隐含的静态成员 class。

1 //clazz就是一个User的类对象
2 Class<?> clazz=User.class;

第三种:通过 Class 类的静态方法 forName() 方法获取。

1 Class<?> clazz = Class.forName("com.tian.User");

 

 

六、Java中关键字的作用

1. finally的重要性

  • 无论是否抛出异常,finally代码块总是会被执行。
  • 就算是没有catch语句同时又抛出异常的情况下,finally代码块仍然会被执行。
  • 最后要说的是,finally代码块主要用来释放资源,比如:I/O缓冲区,数据库连接。

finally小结

try中有return,finally还会执行吗?

  1. try中有return, 会先将值暂存,无论finally语句中对该值做什么处理,最终返回的都是try语句中的暂存值。
  2. 当try与finally语句中均有return语句,会忽略try中return。

2. final和static的区别

  相同:可以修饰类,成员属性,方法。修饰的方法都不能被重写。都不能修饰构造方法

  不同:static可以修饰代码块,final不行。final可以修饰方法内的局部变量,static不可以

3. final有哪些用法?

  • 被final修饰的类不可以被继承
  • 被final修饰的方法不可以被重写
  • 被final修饰的变量不可以被改变.如果修饰引用,那么表示引用不可变,引用指向的内容可变.
  • 被final修饰的方法,JVM会尝试将其内联,以提高运行效率
  • 被final修饰的常量,在编译阶段会存入常量池中

4. try catch finally,try里有return,finally还执行么?

执行,并且finally的执行早于try里面的return。

结论:
1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

七、IO

1. IO的详细区分图解

2. BIO、NIO、AIO 有什么区别?

BIO:Block IO  同步阻塞IO,就是我们平常使用的传统IO,它的特点是简单使用方便,并发处理能力低。

NIO:New IO  同步非阻塞IO,是传统IO的升级,客户端和服务器端通过channel(通道)通讯,实现了多路复用。

AIO:Asynchronous  是NIO的升级,也叫NIO2,实现了异步非阻塞IO,异步IO的操作基于事件和回调机制。

补充:NIO主要用到的是块,所以NIO的效率要比IO高很多。在Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO

 

八、网络编程

1、Java网络程序设计中,下列正确的描述是()

  • Java网络编程API建立在Socket基础之上

  • Java网络接口只支持tcP以及其上层协议

  • Java网络接口只支持UDP以及其上层协议

  • Java网络接口支持IP以上的所有高层协议

一个“只”字暴露了这道题哪个是错的,正确解析跳转

九、其他题目

1. Java中equals方法和hashcode方法起到什么作用?为什么在重写equals时要重写hashcode?

 共同作用:

① 可以保证对象不重复

重写hashcode原因:

① 提高效率,可以避免每次比对都调用equal。

② 保证是同一个对象,如果重写equals,不重写hashcode,则会出现equals结果相等,而hashcode不等。

HashSet在添加元素时的动作:

① 先调用元素hashcode方法

② 根据hashcode返回值来决定元素的插入位置

③ 如果该位置存在相同的hashcode,则用equals比较

④ 如果两个元素相等,则丢掉欲插入的元素

⑤ 如果两个元素不等,则新元素会插入到另一个位置,(通过冲突检测来决定哪个位置)

2. Java的四种引用

3. 堆和栈区别

4. 浅拷贝和深拷贝区别?

5. 常用设计模式

6. Java中的序列化是什么?如果有字段不想序列化怎么办?

对于不想进行序列化的变量,使用 transient 关键字修饰。

7. 有没有可能两个不相等的对象有相同的hashcode?

有可能.在产生hash冲突时,两个不相等的对象就会有相同的 hashcode 值.当hash冲突产生时,一般有以下几种方式处理:

  1. 拉链法:每个哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被分配到同一个索引上的多个节点可以用这个单向链表进行存储。
  2. 再哈希:又叫双哈希法,有多个不同的Hash函数.当发生冲突时,使用第二个,第三个….等哈希函数计算地址,直到无冲突。
  3. 开放定址法:一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入。

8、OOM你遇到过哪些情况,SOF你遇到过哪些情况

OOM:

1,OutOfMemoryError异常

除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的
可能。
Java Heap 溢出:
一般的异常信息:java.lang.OutOfMemoryError:Java heap spacess。
java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来
避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常。

出现这种异常,一般手段是先通过内存映像分析工具(如Eclipse Memory Analyzer)对dump出来的
堆转存快照进行分析,重点是确认内存中的对象是否是必要的,先分清是因为内存泄漏(Memory
Leak)还是内存溢出(Memory Overflow)。
如果是内存泄漏,可进一步通过工具查看泄漏对象到GCRoots的引用链。于是就能找到泄漏对象是
通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收。
如果不存在泄漏,那就应该检查虚拟机的参数(-Xmx与-Xms)的设置是否适当。

2,虚拟机栈和本地方法栈溢出

如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。
如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常
这里需要注意当栈的大小越大可分配的线程数就越少。

3,运行时常量池溢出

异常信息:java.lang.OutOfMemoryError:PermGenspace
如果要向运行时常量池中添加内容,最简单的做法就是使用String.intern()这个Native方法。该方法
的作用是:如果池中已经包含一个等于此String的字符串,则返回代表池中这个字符串的String对
象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。由于常量
池分配在方法区内,我们可以通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接
限制其中常量池的容量。

4,方法区溢出

方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。也有可
能是方法区中保存的class对象没有被及时回收掉或者class信息占用的内存超过了我们配置。
异常信息:java.lang.OutOfMemoryError:PermGenspace
方法区溢出也是一种常见的内存溢出异常,一个类如果要被垃圾收集器回收,判定条件是很苛刻
的。在经常动态生成大量Class的应用中,要特别注意这点。
SOF(堆栈溢出StackOverflow):
StackOverflowError 的定义:当应用程序递归太深而发生堆栈溢出时,抛出该错误。
因为栈一般默认为1-2m,一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容
量超过1m而导致溢出。
栈溢出的原因:递归调用,大量循环或死循环,全局变量是否过多,数组、List、map数据过大。

、其他

1. 跳出多重嵌套循环的几种方法?

①标号方式,在外层定义循环标记【ok:】,break ok。代码示例:

 1 public static void main(String[] args)  {
 2         OK:
 3             for(int i=0;i<10;i++){
 4                 for(int j=0;j<10;j++){
 5                     System.out.println("i,j: "+i+","+j);
 6                     if(i==2){
 7                         break OK;
 8                     }
 9                 }
10             }   
11 }

②使用布尔值变量作为flag,变量值放到for循环的条件中。代码示例:

 1 public static void main(String[] args)  {
 2         boolean forBreak = true;
 3             for(int i=0;i<10;i++){
 4                 for(int j=0;(j<10)&&(forBreak);j++){
 5                     System.out.println("i,j: "+i+","+j);
 6                     if(i==2){
 7                         forBreak = false;
 8                     }
 9                 }
10             }       
11     }

③抛出异常

2.for和while的区别

  --  控制条件语句的那个变量,在for循环结束之后就不能再被访问了,而while循环结束后,还可以继续使用那个变量。如果想继续使用那个变量就用while,否则就for

       原因是for循环结束之后那个变量就从内存中消失,能够提高内存的使用效率

  --  在已知循环次数时使用for,未知循环次数使用while

3. 静态变量和实例变量的区别?

静态变量由static修饰,也称类变量

静态变量在内存中有且仅有一份拷贝

静态变量可以实现让多个对象共享内存

静态变量属于类,不属于任何对象;实例变量必须依存于某一实例 

posted @ 2021-10-24 21:48  E_lian  阅读(323)  评论(0编辑  收藏  举报