Java回顾2【笔记】

String前言

通过六个题目彻底掌握String笔试面试题
String x = "abc";
String y = new String("abcd");

注意:new 出来的堆中的对象也是指向常量池的,存的是地址
Java中String对象在堆和常量池中的情况及比较

0. ==比较地址,equals被重写后是比较内容

1. 内部类
	 --成员内部类
	 ------	--静态内部类
	 ------	--非静态内部类
	 --局部内部类(在方法体内的)
	 ------ --匿名内部类
	 ------ --局部内部类

static class Inner{} 内部和正常类一样,可以存在静态与非静态
但他仍得遵循静态的原则,不能使用外部类的非静态成员
外部类中使用他,正常调用,例如类名.静态,对象名.非静态
外部类外使用他,例如Outer.Inner in = new Outer.Inner();就是在基础上多加一个外部类的名字

class Inner{} 内部不能出现任何和static有关声明
可以随意使用外部的成员,因为这个类不是静态的,所以外部的静态方法不能调用他
外部类中使用他,应该是正常调用
外部类外使用他,巨奇葩,先创建外部对象Outer out = new Outer();
			再Outer.Inner in = out.new Inner();

new Person(){ public void shout(){System.out.println("***u!");} }.shout();
直接重写Person的方法并且调用

局部内部类,算了,估计也用不到,浪费脑容量。修饰符只能有abstract或final...





2. 枚举
   public enum Season{SPRING, SUMMER, AUTUMN, WINTER; private Season(){}} 默认继承了java.lang.Enum
   实际上,前面四个季节相当于public static final Season SPRING = new Season();
   也就是说,枚举就是先帮你创建好几个单例对象,供你使用
   所以SPRING("春天")这样是可以的,只要你写一个构造函数即可,也可以重写toString()

3. 注解
   public @interface Person{ String value() default "人";} 注解中只有属性,default可加可不加
   不太理解,注解有啥用?我写了个value,但注解在方法上以后又有什么效果呢?
   明白了,注解只是设置一下属性,然后需要通过反射去获取注解的属性。要结合!!!反射!!!使用才有用
   	系统预定义的三个注解:@Override @SuppressWarnings @Deprecated(过时)
	文档注释注解:@author @see @since...

   元注解:注解的注解
	@Target:位置
	@Rentention:滞留阶段
	@Documented:是否读取到API
	@Inherited:是否被子类继承

4. 异常Throwable
	--Error(严重错误,不需要catch)
	--Exception
   	-------	--RuntimeException or 子类 NullPointerException ClassCastException IndexOutOfBoundsException
	-------	--编译时异常:FileNotFoundException IOException SQLException
   解决方法:
   运行时异常throw new NullPointerException("空指针异常!")
   编译时异常throws/try catch,抛出或者catch

   运行时异常不需要写在try catch里,例如if else里即可。
   可以自己写一个类继承RuntimeException,然后写带msg参数的构造方法,再重写getMessage()方法
   如果用的是自定义的异常,会要求你抛出,抛出后再被catch到,e.getMessage()。如果不重写getMessage()方法的话就不会显示内容。
   
   当出现return 和 finally。return之前,必定会走一遍finally。

5. 包装类 自动拆/装箱 缓存对象 Byte,Short,Integer,Long都有-128~127; Character为0~127,在这个缓存范围中,他们仍存储在栈中。
   Integer.parseInt(String s)
   Integer.toBinaryString()
	  .toOctalString()
	  .toHexString()
   MAX_VALUE/MIN_VALUE
   Character.toUpperCase('a')
	    .toLowerCase('A')
	

补充:
6. Date SimpleDateFormat Calendar

7. 泛型 来告知这个瓶子里要装什么东西,泛型必须得是引用数据类型 
   泛型类:
	public class ArrayList<E>{}
   泛型方法:
	public <T> void test(){} 不知道有啥意义
   未设定泛型,泛型被擦除会解析为泛型形参的第一个上限的类型,若没有extends就为Object 例如<T extends Number & Comparable>

8. 单例

public class Lazy(){
	private Lazy(){}

	private static class Inner{
		public static final Lazy INSTANCE = new Lazy();
	}

	public static Lazy getInstance(){
		return Inner.Instance;
	}
}

9. String
   其对象不可变,只要修改字符串就会产生新的对象,新对象会放在常量池中

   常量池在哪?JDK1.6方法区,JDK1.7堆,JDK1.8元空间

   String对象底层的存储,private final char[],JDK1.9 private final byte[]

对象题
   第一题:String s = new String("hello");//创建了几个对象

   第二题:
   String s1 = new String("world");
   String s2 = new String("world");//创建了几个对象

   第一题为2个,new String()在堆中创建了一个对象存储world,world在常量池创建了一个对象
   第二题为3个,两个new String()创建了两个,world重复了,只创建了一个

地址题 
   常量+常量->常量池
   常量+变量->堆
   s.intern()->常量池
   
   我自己的理解可能有误,例如name="L",此时我的name指向的是常量池的,所以拿name去==比较时他是常量池的
   而我把name作为变量与其他String相加的时候,它就是作为变量相加,所以相加后的结果就为堆

作为形参
   String作为形参传入方法,并修改值,不会对实参造成影响
   而普通对象作为形参传入方法,利用set方法,会对实参造成影响,为什么呢?

	详细解释在Java回顾1的底下的题目那一块有说明。在此粗略解释:
	因为其实实参和形参的传递仅仅只是一次赋值而已,就是给形参赋了值,他们俩之间并没有其他关系。这样明白了么

包装类题目:

Integer i = 1;
Integer j = 1;
System.out.println(i == j);//true

Integer i = 128;
Integer j = 128;
System.out.println(i == j);//false

Integer i = new Integer(1);//新new的在堆中
Integer j = 1;//这个用的是缓冲的常量对象,在方法区
System.out.println(i == j);//false

Integer i = new Integer(1);//新new的在堆中
Integer j = new Integer(1);//另一个新new的在堆中
System.out.println(i == j);//false

Integer i = new Integer(1);
int j = 1;
System.out.println(i == j);//true,凡是和基本数据类型比较,都会先拆箱,按照基本数据类型的规则比较

String题目:

	@Test
	public void test06(){
		String s1 = "hello";
		String s2 = "world";
		String s3 = "helloworld";
		
		String s4 = (s1 + "world").intern();//把拼接的结果放到常量池中
		String s5 = (s1 + s2).intern();
		
		System.out.println(s3 == s4);//true
		System.out.println(s3 == s5);//true
	}
	
	@Test
	public void test05(){
		final String s1 = "hello";
		final String s2 = "world";
		String s3 = "helloworld";
		
		String s4 = s1 + "world";//s4字符串内容也helloworld,s1是常量,"world"常量,常量+ 常量 结果在常量池中
		String s5 = s1 + s2;//s5字符串内容也helloworld,s1和s2都是常量,常量+ 常量 结果在常量池中
		String s6 = "hello" + "world";//常量+ 常量 结果在常量池中,因为编译期间就可以确定结果
		
		System.out.println(s3 == s4);//true
		System.out.println(s3 == s5);//true
		System.out.println(s3 == s6);//true
	}
	
	@Test
	public void test04(){
		String s1 = "hello";
		String s2 = "world";
		String s3 = "helloworld";
		
		String s4 = s1 + "world";//s4字符串内容也helloworld,s1是变量,"world"常量,变量 + 常量的结果在堆中
		String s5 = s1 + s2;//s5字符串内容也helloworld,s1和s2都是变量,变量 + 变量的结果在堆中
		String s6 = "hello" + "world";//常量+ 常量 结果在常量池中,因为编译期间就可以确定结果
		
		System.out.println(s3 == s4);//false
		System.out.println(s3 == s5);//false
		System.out.println(s3 == s6);//true
	}

/*--------------------------4-----------------------------*/
    public static void main(String[] args) {   
            String ab = "ab";   
            final String b = getBB();   
            String ab2 = "a" + b;   
            System.out.println(ab == ab2);//!!!!!!!!!!false,因为getBB就是堆中的,即便定义为final他也不是常量
        }   
      
        private static String getBB() {   
            return "b";   
        } 

陌生所以绝对重要:

集合底层/多线程(锁)/反射/IO

序列化/类加载过程...

1.8新特性/网络

posted @ 2021-04-13 12:08  lwxx  阅读(80)  评论(0)    收藏  举报