java基础笔记(4)内部类,静态内部类,局部内部类,匿名内部类,异常

1.内部类
成员内部类
1.可以使用四种访问权限修饰符修饰的
2. 局部变量是不能用static修饰的
3. 内部类字节码文件命名方式 外部类$内部类.class
4. 内部类是可以使用外部类的属性和方法的,包括私有的
5. 外部类属性和内部类属性同名的时候优先使用内部类的
6. 即使用this也是使用的内部类的,除非创建外部类对象调用
7. 使用内部类的时候必须要导包
8. 内部类创建方式 要通过 外部类对象创建内部类对象
里面包裹的类 : 内部类
外面的类: 外部类, 宿主类
四类:
成员内部类
静态内部类
局部内部类
匿名内部类

public class Car {
    
    
	String color = "绿色";
	private void run() {
    
    
		System.out.println("跑");	
	}
	public class 发动机{
    
    
		String color = "红色的";
		String type;		
		public void work() {
    
    
			System.out.println("发动机");
			run();
			System.out.println(new Car().color);
		}
	}
}
import demo.Car.发动机;
public class Test {
    
    
	public static void main(String[] args) {
    
    
		Car car = new Car();
		car.color = "绿色";		
		发动机 f = car.new 发动机();
		发动机 f2 = new Car().new 发动机();
		f2.type = "345";
		f2.work();
	}
	class Test2{
    
    
		public void a() {
    
    			
		}
	}
}

2.静态内部类
1.静态内部类中可以使用静态的属性和方法
2.字节码文件的名字 外部类$内部类.class
3.静态内部类中 不能直接使用外部类的非静态的属性和方法
4内部类中的属性和外部类属性同名的时候, 可以通过外部类.静态属性 调用外部类属性
5.静态内部类可以直接创建对象 不需要外部类对象

public class Outer {
    
    
	static String name;
	int age;	
	public void run() {
    
    
		System.out.println("跑");		
	}
	static class Inner{
    
     
		int a;
		static int b;
		static String name;
		public void a() {
    
    
			System.out.println("a");
			System.out.println(Outer.name);
		}
		public static void b() {
    
    
			System.out.println("static的b");
		}
	}
}
import demo2.Outer.Inner;
public class Test {
    
    
	public static void main(String[] args) {
    
    
		Inner inner = new Inner();		
	}
}

3.局部内部类
局部内部类 类似于一个局部变量
1.局部内部类定义在方法内部的类
2. 不能使用访问权限修饰符以及 static进行修饰
3. 局部内部类中可以使用 外部类的属性也可以使用方法中的局部变量
4. 如果局部内部类中的属性和外部类成员属性同名, 则可以使用外部类.this.属性 调用外部类的属性
5. 局部内部类只能在声明此内部类的方法中创建对象
6. 局部内部内部类只能方法被调用的时候,才能执行

public class Test {
    
    
	int a = 3;
	public static void main(String[] args) {
    
    
		Test test = new Test();
		test.test();
	}
	public void test() {
    
    
		int age = 3;
class Inner{
    
    
			public String name = "mingzi";
			private int a = 5;
			public void show() {
    
    
				System.out.println(name);
				System.out.println(age);
				System.out.println(Test.this.a);
			}
		}
		Inner inner = new Inner();
		inner.show();
	}
}

4.匿名内部类
1.没有自己本类的名字, 只能拿接口或者抽象类的名字代表
2.创建的是实现类或者子类的对象
左边是接口的名字 = 右边是实现类的对象 向上转型
3.不会再匿名内部类中新增 特有方法, 因为没有办法通过接口名字调用
3. 即使一个内部类或者接口 ,new了多次, 是多个实现类
4. 当有实现类或者子类只需要创建一次对象,则可以使用匿名内部类. 可以使程序结构更加简洁
5. 匿名内部类的名字 外部类$数字.class
匿名内部类中可以额外定义自己的方法, 但是一般不这样做

public class Test {
    
    
	public static void main(String[] args) {
    
    
		MyRunnable runnable = new MyRunnable();
		runnable.run();
		// 只想创建一个实现类的对象 , 调用一次run方法
				// 利用匿名内部类的写法
		Runnable runnable2 = new Runnable() {
    
    
			
			@Override
			public void run() {
    
    
				System.out.println("线程2");
			}
		};
		runnable2.run();
	}
}
class MyRunnable implements Runnable{
    
    
	@Override
	public void run() {
    
    
	System.out.println("线程");
	}
}
public abstract class AbstractClass {
    
    
	public abstract void b();
}
public class Animal implements Run{
    
    
	@Override
	public void run() {
    
    
	System.out.println("动物跑步");
	}
}
public class Person implements Run{
    
    
	@Override
	public void run() {
    
    
	System.out.println("人跑步");
	}
	public void eat() {
    
    		
	}
}
public interface Run {
    
    
	public void run();
}
public class Test3 {
    
    
	public static void main(String[] args) {
    
    
		Person person = new Person();
		person.run();		
		Animal animal = new Animal();
		animal.run();		
		Run run = new Run() {
    
    			
			@Override
			public void run() {
    
    
				System.out.println("外星人跑步");
				eat();
			}
			public void eat() {
    
    				
			}
		};
		run.run();		
		//创建抽象类对象
		AbstractClass class1 = new AbstractClass() {
    
    			
			@Override
			public void b() {
    
    
				System.out.println("bbb");
			}
		};
		class1.b();		
		AbstractClass class2  = new AbstractClass() {
    
    			
			@Override
			public void b() {
    
    
				System.out.println("bbb");
			}
		};
		class2.b();
	}
}

基本数据类型在参数传递的时候,传递的是 数值
引用数据类型在参数传递的时候,传递的是地址(引用)
值传递 和引用传递
注意:
String字符串作为参数的时候,传递的是 地址(引用),但是常量池存储数据的特点:
如果即将要存储的数据在常量池中存在,则直接使用, 如果不存在,则重新开辟新的空间存储, 绝对不会修改内容

public class Person {
    
    
	String name;
	int age;
}
public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		Person p = new Person();
		p.name = "lisi";
		p.age = 15;		
		a(p);
		System.out.println("main-->"+p.name+" "+p.age);
	}
	public static void a(Person p) {
    
    
		p.name = "zhangsan";
		p.age = 5;
		System.out.println("a-->"+p.name+" "+p.age);
	}
}

5.异常
运行时异常
非运行时异常,编译时期就会报错,必须处理,不处理就无法运行 涉及到外界资源, 有可能会因为外界资源的改变导致 出现问题,无论是否发生异常都要求处理以后才能执行 , 在编译实际就会 提示
程序如果发生了异常
先执行try 代码块,发现异常,jvm自动的创建异常的对象 ,查找能够捕获异常的代码找catch,如果catch中的类型和异常类型匹配则执行catch块进行处理异常,程序继续向下执行,不会中断,如果catch中类型不匹配,则直接爆出异常, 让程序中断
如果没有发生异常:
先执行try块,如果没有异常则执行完try以后执行 不执行catch
finally无论是否发生异常 都会执行此代码
资源清理和关闭的操作,还有直接退出系统 才不执行 否则一定会执行 即使 return break也必须要执行
System.exit(0);不执行
throws 可以跟多个异常类型, 标明方法内部可能存在异常, 如果发生异常 将异常转给调用者,标明异常存在的可能性 抛出异常
throws 异常发生的可能性 , 声明异常 , 写在方法声明后面 , 跟的异常类型,可以跟多个,
throw产生异常,抛出异常 , 方法内部的, 跟的是异常对象, 只能跟一个,只要出现了throw 通常会结合throws 使用,throw 后面跟的是异常对象, 真正产生异常
如果想要自定义非运行时异常 继承Exception
只有继承了RuntimeException 才是运行时异常

  1. 异常体系中:
    Thrwable
    Error: 严重性错误, 没有办法直接解决, 只能尽量避免
    Exception : 异常,通常都是逻辑错误导致的 , 可以解决
  2. 异常的处理机制:
    当发生异常的时候,会产生异常对象, 去查找处理异常的代码, 如果找到则交由其处理, 程序正常运行
    没有找到则 程序终止
  3. 异常的分类:
    运行时异常(非受检异常)
    非运行时异常(受检异常,编译时异常)
  4. 处理异常的方式
    try
    catch
    finally
  5. throw 和throws
    throws 异常发生的可能性 , 声明异常 , 写在方法声明后面 , 跟的异常类型,可以跟多个
    throw new NullPointerException();// 产生异常 抛出异常 , 方法内部的, 跟的是异常对象, 只能跟一个
    只要出现了throw 通常会结合throws 使用
  6. 自定义异常: 针对于业务逻辑可能会要求写一些 异常,
    自定异常:
    继承RuntimeException 运行时异常,
    继承Exception 非运行时异常. 非运行时异常通常都是与外界资源有联系
public class LegException extends Exception{
    
    
	public LegException() {
    
    
		super();
	}
	public LegException(String message) {
    
    
		super(message);
	}
}
public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		try {
    
    
		a(2,"猫");
		} catch (LegException e) {
    
    
			// TODO: handle exception
		}
		System.out.println("正常运行");
	}
	public static void a(int leg,String animal)throws LegException {
    
    
		if("猫".equals(animal) && leg ==4) {
    
    
			System.out.println("猫四条腿");
		}else {
    
    
			System.out.println("腿数不正确");
		}
	}
}
public class SexException extends RuntimeException{
    
    
	public SexException() {
    
    
		super();
	}
	public SexException(String message) {
    
    
		super(message);
	}
}
public class Test {
    
    
	public static void main(String[] args) {
    
    
		try {
    
    
			a("呵呵");
		} catch (SexException e) {
    
    
			System.out.println(e.getMessage());
			e.printStackTrace();
			}
		System.out.println("正常运行");
	}
	public static void a(String gender) throws SexException {
    
    
		if("男".equals(gender) || "女".equals(gender)) {
    
    
			System.out.println("性别正常");
		}else {
    
    
			throw new SexException("性别超过正常范围");
		}		
	}
}

猜你喜欢

转载自blog.csdn.net/Echoxxxxx/article/details/112442375