java基础-----第二关

内部类

基础
java中可以将一个类定义在另一个类里面或者方法中,这样的类称为内部类。分为:成员内部类、局部内部类、匿名内部类、静态内部类。
一个java文件中可以定义多个类,但是只能有一个使用public修饰,且这个类必须和文件名相同。
成员内部类
最普通的内部类,将一个类定义在另一个类的内部。

class A{ 
	private static int b=10;
	private int a = 0;
    public A(int a) {
        this.a = a;
    }
    class B{     //内部类
        public void Bway() {
            System.out.println("Bway");
            System.out.println(a);
            System.out.println(b);
        }
    }
}

1.成员内部类可以无条件的访问外部类的成员属性和方法(private也可以)。
2.若成员内部类与外部类成员属性方法发生冲突时,内部类中优先调用内部类,访问方式
(外部类.this.成员变量)(外部类.this.成员方法)
3.外部类访问内部类成员时,需要先实例内部类对象。(new B().方法())
4.在另一个类中调用内部类成员,必须先实例外部类对象,再通过外部类对象实例内部类对象。
(A a = new A(); A.B b = a.new B();)

局部内部类
局部内部类是定义在一个方法内或者一个作用域里面的类。
与成员内部类的区别在于局部内部类的访问权限仅在方法内或者作用域内。
局部内部类不能用public、protected、private 以及 static 修饰符的,只能用final修饰内部类。

class A{
    public A(){ 
    }
    public void Away(){
        class B{   //局部内部类
            int age =0;
        }
        B b = new B();
        b.age=10;
    }
}

匿名内部类
最常用的内部类,没有名字,定义在其他类方法中的类。
把定义子类、重写父类的方法、创建子类对象,合成一步完成

new A(){
	public void Away(){
        //重写父类的方法
    }
};

静态内部类
静态内部类也是定义在另一个类里面的类,前面多了一个static关键字。
静态内部类是不需要外部类的,可以不用实例化外部类。
静态内部类不能使用外部类中非static的成员变量或者方法。

public class demo {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Outter.Inner inner = new Outter.Inner();
	}
}
class Outter {
    public Outter() {        
    }
     
    static class Inner {
        public Inner() {
        }
    }
}

集合

与数组的区别
长度:集合可变;数组固定
内容:集合只能引用类型;数组可以基本类型,可以引用类型。
元素:集合可以存储不同类型(一般一种),数组只能存储同一种类型。
在这里插入图片描述
Collection接口:接口的接口,单列集合的接口
******** list接口:元素按照先后顺序保存,可重复,有序
**************** LinkedList:接口实现类,底层链表,没有同步,线程不安全
**************** ArrayList:接口实现类,底层数组,没有同步,线程不安全
**************** Vector:接口实现类,底层数组,同步,线程安全
******** set接口:内部排序,不可重复
**************** HashSet:使用hash表存储,底层数组,没有同步,线程不安全
************************* LinkedHashSet:底层链表,有序,不可重复,没有同步,线程不安全
**************** TreeSet: 底层二叉树,最底层TreeMap,自动排序、不可重复、没有同步、线程不安全
Map接口:键值对集合,双列集合的接口
******** Hashtable:接口实现类,同步,线程安全
******** HashMap:接口实现类,没有同步,线程不安全
**************** LinkedHashMap:双向链表与哈希表实现,有序,没有同步,线程不安全
******** TreeMap:红黑数对所有的key进行排序、没有同步,线程不安全
HashMap可以将null设为键,也可以设为值。
Hashtable不可以将null设为键,也不可以设为值。

反射

定义
java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为反射。
必须先要获取到该类的字节码文件对象。解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象

用法
遇到某个类的某个成员变量、方法是私有的或者有权限问题,就可以用反射机制获取私有成员或方法。

类的加载
1).对于任何一个类,当程序中第一次使用这个类时(第一次创建对象、第一次调用这个类中静态成员) JVM会先加载这个类的class文件,并在"方法区"创建一个"Class对象",这个对象中会存储这个类的内部的一些信息:构造方法、成员属性、成员方法…。
2).之后再使用这个类的时候,JVM就不会再去找这个类的class文件了,直接通过之前创建的"Class对象"就可以获取这个类的内部信息,并创建这个类的对象。
3).对于任何一个类,在"方法区"中,都会有,而且只有一个这个类的"Class对象"。

Class对象的初始化时机
1).当一个类第一次被创建对象时;
2).当第一次访问这个类中的静态成员(静态属性、静态方法)时;
3).使用"反射"获取一个类的Class对象时;【今天学习的】
4).当第一使用这个类的"子类"时;

名词
1).Class:类
2).Constructor:构造
3).Method:方法
4).Filed:字段(成员属性或者成员变量)
5).instance:实例
6).invoke:执行

获取Class的方法

package reflection;
/**
 * 获取Class对象的三种方式
 * 1 Object ——> getClass();
 * 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
 * 3 通过Class类的静态方法:forName(String  className)(常用)
 */
public class reflection{
	public static void main(String[] args) {
		//第一种方式获取Class对象  
		Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
		Class stuClass = stu1.getClass();//获取Class对象
		System.out.println(stuClass.getName());

		//第二种方式获取Class对象
		Class stuClass2 = Student.class;
		System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
		
		//第三种方式获取Class对象
		try {
			Class stuClass3 = Class.forName("reflection.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
			System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

异常

分类
在这里插入图片描述
Error:是程序中无法处理的错误,表示运行应用程序中出现了严重的错误。
Exception:程序本身可以捕获并且可以处理的异常。

异常的处理
抛出异常:throw,throws (throw在方法内使用抛出,throws在方法上进行声明使用)
捕获异常:try,catch,finally

try{
	可能出现的异常的代码
}catch(异常类型 变量名){
	catch中异常类型必须是所有可能出现异常类型的父类
	处理异常一般打印异常信息
	syso(变量名);
	变量名.printStackTrace();
}finally{
	关闭资源的代码
	如果关闭资源的代码也可能出现异常
	直接用try..catch包括即可
}

网络编程

网络编程的目的就是直接或间接地通过网络协议与其他计算机进行通信。在Java中包含网络编程地各种类,通过创建这些类的对象,调用相应的方法,就可以进行网络应用程序的编写。ServerSocket 是服务端、Socket是客户端。
ServerSocket 构造方法
ServerSocket():无参构造方法。
ServerSocket(int port):创建绑定到特定端口的服务器套接字。
ServerSocket(int port,int backlog):使用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口。
ServerSocket(int port,int backlog,InetAddress bindAddr):使用指定的端口、监听 backlog 和要绑定到本地的 IP 地址创建服务器

ServerSocket 的常用方法
Server accept():监听并接收到此套接字的连接。
void bind(SocketAddress endpoint):将 ServerSocket 绑定到指定地址(IP 地址和端口号)。
void close():关闭此套接字。
InetAddress getInetAddress():返回此服务器套接字的本地地址。
int getLocalPort():返回此套接字监听的端口。
SocketAddress getLocalSoclcetAddress():返回此套接字绑定的端口的地址,如果尚未绑定则返回 null。
int getReceiveBufferSize():获取此 ServerSocket 的 SO_RCVBUF 选项的值,该值是从 ServerSocket 接收的套接字的建议缓冲区大小

Socket 的构造方法
Socket():无参构造方法。
Socket(InetAddress address,int port):创建一个流套接字并将其连接到指定 IP 地址的指定端口。
Soclcet(InetAddress address,int port,InetAddress localAddr,int localPort):创建一个套接字并将其连接到指定远程地址上的指定远程端口。
Socket(String host,int port):创建一个流套接字并将其连接到指定主机上的指定端口。
Socket(String host,int port,InetAddress localAddr,int localPort):创建一个套接字并将其连接到指定远程地址上的指定远程端口。Socket 会通过调用 bind() 函数来绑定提供的本地地址及端口。
address 指的是远程地址,port 指的是远程端口,localAddr 指的是要将套接字绑定到的本地地址,localPort 指的是要将套接字绑定到的本地端口

Socket 的常用方法
void bind(SocketAddress bindpoint):将套接字绑定到本地地址。
void close():关闭此套接字。
void connect(SocketAddress endpoint):将此套接字连接到服务器。
InetAddress getInetAddress():返回套接字的连接地址。
InetAddress getLocalAddress():获取套接字绑定的本地地址。
InputStream getInputStream():返回此套接字的输入流。
OutputStream getOutputStream():返回此套接字的输出流。
SocketAddress getLocalSocketAddress():返回此套接字绑定的端点地址,如果尚未绑定则返回 null。
SocketAddress getRemoteSocketAddress():返回此套接字的连接的端点地址,如果尚未连接则返回 null。
int getLoacalPort():返回此套接字绑定的本地端口。
intgetPort():返回此套接字连接的远程端口。

/**
 * 服务器端
 */
public class Server {
    public static void main(String[] args) {
        //5.创建ServerSocket、Socket、OutputStream、InputStream以及端口号并初始化
        ServerSocket serverSocket = null;
        Socket socket = null;
        OutputStream out = null;
        InputStream in = null;
        int port = 5000;
        try {
            //6.开启服务器并接收客户端发送的数据
            serverSocket = new ServerSocket(port);//创建服务器套接字
            System.out.println("服务器开启,等待连接...");
            socket = serverSocket.accept();//获得连接
            //接收客户端发送的内容
            in = socket.getInputStream();
            byte[] b = new byte[1024];
            int len = in.read(b);
            System.out.println("客户端发送的内容为:" + new String(b,0,len));
            //7.使用输出流对象将信息返回给客户端
            out = socket.getOutputStream();
            out.write("我是服务器端".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //8.关闭流对象、ServerSocket对象以及Socket对象
            try {
                in.close();
                out.close();
                serverSocket.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        //1.定义 Socket 对象、OutputStream 对象和一个 InputStream 对象并完成初始化
        Socket socket = null;
        OutputStream out = null;
        InputStream in = null;
        //定义服务器端的 IP 地址和端口号
        String serverIP = "127.0.0.1";//服务器端 IP 地址
        int port = 5000;//服务器端端口号
        try {
            //2.建立与服务器端的连接并将数据发送到服务器端
            socket = new Socket(serverIP, port);//建立连接
            out = socket.getOutputStream();//发送数据
            out.write("我是客户端数据".getBytes());
            Thread.sleep(1000);
            
            //3.从输入流中读出服务器的反馈信息并输出到控制台
            byte[] b = new byte[1024];
            in = socket.getInputStream();
            int len = in.read(b);
            System.out.println("服务器端的反馈为:" + new String(b, 0, len));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4.关闭流及 Socket 对象
            try {
                in.close();
                out.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 第6中的"final"键字是Java语言中的一个修饰符,它可以用来修饰类、方法和变量。 1. 修饰类:使用final修饰的类不能被继承。 2. 修饰方法:使用final修饰的方法不能被子类重写。 3. 修饰变量:使用final修饰的变量变为常量,一旦赋值后不能再次赋值。 使用final键字时需要注意: 1. final修饰的类中所有方法都隐式为final。 2. final修饰的变量必须在声明时或构造器中赋值,否则编译错误。 3. 对于基本数据类型,final修饰的变量的值不能改变,对于引用数据类型,final修饰的变量引用的对象的内容可以改变. ### 回答2: final是Java中的一个键字,它可以用于修饰类、方法和变量。在这里,我们主要讨论final在修饰变量时的用途和作用。 一、变量被final修饰时具有不变性 当一个变量被final修饰时,它的值就不可以再次被修改,因此,我们称之为“常量”。final常量在定义时必须进行初始化,一旦被初始化后就不能再次改变了。 final修饰的变量通常采用大写字母命名,这样可以区分出普通的变量和常量。例如: final int MAX_LENGTH = 100; 这里我们定义了一个常量MAX_LENGTH,它的值为100,无论什么时候都不再改变。 二、final键字可以提高程序的效率 使用final修饰变量时,编译器会对其进行优化,避免变量被重复赋值。 例如,在循环中使用final修饰的变量: for (final int i = 0; i < 100; i++) { // do something } 在这个循环中,i被final修饰后,编译器会在每次循环时将i的值缓存起来,避免多次访问内存。这样可以有效地提高代码的执行效率。 三、final修饰的变量可以保证数据的安全性 假设一个变量被多个线程共享,如果没有使用final修饰,那么这个变量的值可能会被不同的线程修改。这样就会产生数据的混乱,导致程序出现错误。 而使用final修饰变量后,它的值不可变,线程间就不会产生数据冲突。因此,使用final修饰变量可以提高程序的健壮性和鲁棒性。 综上所述,final键字可以用来定义常量,提高代码效率,并且保证数据的安全性。在实际编程中,应当合理使用final键字,以提高程序的性能和稳定性。 ### 回答3: final键字在Java中有着非常重要的作用,它可以用于修饰类、方法和变量。对于final修饰的类,表示该类是不可继承的,也就是说不能派生子类来继承这个类。而对于final修饰的方法,表示该方法不能被重写,也就是说不能在子类中重新定义该方法。最后,对于final修饰的变量,表示该变量是一个常量,它的值在初始化后就不能再被改变了。 其实final键字主要的作用就是用来保护程序的安全性和稳定性。比如final修饰的变量,可以避免在程序运行过程中意外的修改变量的值,从而提高程序的可靠性。 另外,final键字还有一个很有用的作用,就是可以用来提高程序的运行效率。因为final修饰的变量在编译时就可以确定其值,所以在程序运行时就可以直接使用该变量的值,而不需要再进行运算,这样就可以提高程序的运行效率。 在使用final键字时,需要注意一些细节问题。比如final修饰的变量必须在声明时或构造函数中初始化,并且不能再被修改。另外,如果一个类被声明为final,则该类中所有的方法都自动成为final方法,因为这些方法都不能被重写。 总之,final键字是Java中非常重要的一部分,它可以用来保护程序的安全性和稳定性,同时也可以提高程序的运行效率。在使用过程中,需要注意一些细节问题,避免出现错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值