Java学习笔记

Java学习笔记

初识Java

  • 1.1Java语言概述
    1991 年Sun 公司的James Gosling 等人开始开发名称为 Oak 的语言,希望用于控制嵌入在有线电视交换盒、PDA 等的微处理器;1994 年将Oak 语言更名为Java;

  • 1.2Java 的三种技术架构
    AVAEE:开发企业环境下的应用程序,主要针对web 程序开发;
    JAVASE:完成桌面应用程序的开发,是其它两者的基础;
    JAVAME:开发电子消费产品和嵌入式设备,如手机中的程序;
    jDK:java 的开发和运行环境,java 的开发工具和jre。
    JRE:java 程序的运行环境,java 运行的所需的类库+JVM(java 虚拟机)。

  • 1.3 Java环境配置

  • 下载JDK
    首先我们需要下载java开发工具包JDK,下载地址:Java安装包,点击如下下载按钮
    Java下载
    安装完成后,右击"我的电脑",点击"属性",选择"高级系统设置"
    在这里2
    选择"高级"选项卡,点击"环境变量"
    3
    然后就会出现如下图所示的画面:
    4
    在 “系统变量” 中设置 3 项属性,JAVA_HOME、PATH、CLASSPATH(大小写无所谓),若已存在则点击"编辑",不存在则点击"新建"。
    变量设置参数如下:
    变量名:JAVA_HOME
    变量值:C:\Program Files (x86)\Java\jdk1.8.0_91 // 要根据自己的实际路径配置
    变量名:CLASSPATH
    变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; //记得前面有个"."
    变量名:Path
    变量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

JAVA_HOME 设置
在这里插入图片描述
PATH设置
在这里插入图片描述
CLASSPATH 设置

在这里插入图片描述
这是 Java 的环境配置,配置完成后,可以启动 Eclipse 来编写代码,它会自动完成java环境的配置。
测试JDK是否安装成功
1、“开始”->“运行”,键入"cmd";
2、键入命令: java -version、java、javac 几个命令,出现以下信息,说明环境变量配置成功;
在这里插入图片描述

  • 1.3 javac Java命令的用途
    要知道java 是分两部分的:一个是编译,一个是运行。javac:负责的是编译的部分,当执行javac 时,会启动java 的编译器程序。对指定扩展名的.java 文件进行编译。 生成了jvm 可以识别的字节码文件。也就是class 文件,也就是java 的运行程序。java:负责运行的部分.会启动jvm.加载运行时所需的类库,并对class 文件进行执行。一个文件要被执行,必须要有一个执行的起始点,这个起始点就是main 函数。
    使用 Eclipse 运行第一个 Java 程序
public class HelloWorld {
    public static void main(String []args) {
        System.out.println("Hello World"); 
    }
}

Java语法
基本语法
编写 Java 程序时,应注意以下几点:
大小写敏感:Java 是大小写敏感的,这就意味着标识符 Hello 与 hello 是不同的。
类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存,文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误)。
主方法入口:所有的 Java 程序由 public static void main(String []args) 方法开始执行。
Java 标识符
Java 所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。

关于 Java 标识符,有以下几点需要注意:

所有的标识符都应该以字母(A-Z 或者 a-z),美元符( ) 、 或 者 下 划 线 ( ) 开 始 首 字 符 之 后 可 以 是 字 母 ( A − Z 或 者 a − z ) , 美 元 符 ( )、或者下划线(_)开始 首字符之后可以是字母(A-Z 或者 a-z),美元符( 线AZaz,)、下划线(_)或数字的任何字符组合
关键字不能用作标识符
标识符是大小写敏感的
合法标识符举例:age、$salary、_value、__1_value
非法标识符举例:123abc、-salary
Java注释
类似于 C/C++、Java 也支持单行以及多行注释。注释中的字符将被 Java 编译器忽略

public class HelloWorld {
   /* 这是第一个Java程序
    *它将打印Hello World
    * 这是一个多行注释的示例
    */
    public static void main(String []args){
       // 这是单行注释的示例
       /* 这个也是单行注释的示例 */
       System.out.println("Hello World"); 
    }
}

Java 基本数据类型
变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。
内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。
在这里插入图片描述
java 的两大数据类型:
内置数据类型
引用数据类型

Java八种基本类型

内置数据类型
Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
byte:
byte 数据类型是8位、有符号的,以二进制补码表示的整数;
最小值是 -128(-2^7);
最大值是 127(2^7-1);
默认值是 0;
byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
例子:byte a = 100,byte b = -50。
short:
short 数据类型是 16 位、有符号的以二进制补码表示的整数
最小值是 -32768(-2^15);
最大值是 32767(2^15 - 1);
Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;
默认值是 0;
例子:short s = 1000,short r = -20000。
int:
int 数据类型是32位、有符号的以二进制补码表示的整数;
最小值是 -2,147,483,648(-2^31);
最大值是 2,147,483,647(2^31 - 1);
一般地整型变量默认为 int 类型;
默认值是 0 ;
例子:int a = 100000, int b = -200000。
long:
long 数据类型是 64 位、有符号的以二进制补码表示的整数;
最小值是 -9,223,372,036,854,775,808(-2^63);
最大值是 9,223,372,036,854,775,807(2^63 -1);
这种类型主要使用在需要比较大整数的系统上;
默认值是 0L;
例子: long a = 100000L,Long b = -200000L。
"L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。
float:
float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;
float 在储存大型浮点数组的时候可节省内存空间;
默认值是 0.0f;
浮点数不能用来表示精确的值,如货币;
例子:float f1 = 234.5f。
double:
double 数据类型是双精度、64 位、符合IEEE 754标准的浮点数;
浮点数的默认类型为double类型;
double类型同样不能表示精确的值,如货币;
默认值是 0.0d;
例子:double d1 = 123.4。
boolean:
boolean数据类型表示一位的信息;
只有两个取值:true 和 false;
这种类型只作为一种标志来记录 true/false 情况;
默认值是 false;
例子:boolean one = true。
char:
char类型是一个单一的 16 位 Unicode 字符;
最小值是 \u0000(即为0);
最大值是 \uffff(即为65,535);
char 数据类型可以储存任何字符;
例子:char letter = ‘A’;。
实例

public class PrimitiveTypeTest {  
    public static void main(String[] args) {  
        // byte  
        System.out.println("基本类型:byte 二进制位数:" + Byte.SIZE);  
        System.out.println("包装类:java.lang.Byte");  
        System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE);  
        System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE);  
        System.out.println();  
  
        // short  
        System.out.println("基本类型:short 二进制位数:" + Short.SIZE);  
        System.out.println("包装类:java.lang.Short");  
        System.out.println("最小值:Short.MIN_VALUE=" + Short.MIN_VALUE);  
        System.out.println("最大值:Short.MAX_VALUE=" + Short.MAX_VALUE);  
        System.out.println();  
  
        // int  
        System.out.println("基本类型:int 二进制位数:" + Integer.SIZE);  
        System.out.println("包装类:java.lang.Integer");  
        System.out.println("最小值:Integer.MIN_VALUE=" + Integer.MIN_VALUE);  
        System.out.println("最大值:Integer.MAX_VALUE=" + Integer.MAX_VALUE);  
        System.out.println();  
  
        // long  
        System.out.println("基本类型:long 二进制位数:" + Long.SIZE);  
        System.out.println("包装类:java.lang.Long");  
        System.out.println("最小值:Long.MIN_VALUE=" + Long.MIN_VALUE);  
        System.out.println("最大值:Long.MAX_VALUE=" + Long.MAX_VALUE);  
        System.out.println();  
  
        // float  
        System.out.println("基本类型:float 二进制位数:" + Float.SIZE);  
        System.out.println("包装类:java.lang.Float");  
        System.out.println("最小值:Float.MIN_VALUE=" + Float.MIN_VALUE);  
        System.out.println("最大值:Float.MAX_VALUE=" + Float.MAX_VALUE);  
        System.out.println();  
  
        // double  
        System.out.println("基本类型:double 二进制位数:" + Double.SIZE);  
        System.out.println("包装类:java.lang.Double");  
        System.out.println("最小值:Double.MIN_VALUE=" + Double.MIN_VALUE);  
        System.out.println("最大值:Double.MAX_VALUE=" + Double.MAX_VALUE);  
        System.out.println();  
  
        // char  
        System.out.println("基本类型:char 二进制位数:" + Character.SIZE);  
        System.out.println("包装类:java.lang.Character");  
        // 以数值形式而不是字符形式将Character.MIN_VALUE输出到控制台  
        System.out.println("最小值:Character.MIN_VALUE="  
                + (int) Character.MIN_VALUE);  
        // 以数值形式而不是字符形式将Character.MAX_VALUE输出到控制台  
        System.out.println("最大值:Character.MAX_VALUE="  
                + (int) Character.MAX_VALUE);  
    }  
}

引用类型
在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。
对象、数组都是引用数据类型。所有引用类型的默认值都是null。一个引用变量可以用来引用任何与之兼容的类型。
例子:Site site = new Site(“Runoob”)。

Java运算符

算术运算符

public class Test {
 
  public static void main(String[] args) {
     int a = 10;
     int b = 20;
     int c = 25;
     int d = 25;
     System.out.println("a + b = " + (a + b) );
     System.out.println("a - b = " + (a - b) );
     System.out.println("a * b = " + (a * b) );
     System.out.println("b / a = " + (b / a) );
     System.out.println("b % a = " + (b % a) );
     System.out.println("c % a = " + (c % a) );
     System.out.println("a++   = " +  (a++) );
     System.out.println("a--   = " +  (a--) );
     System.out.println("d++   = " +  (d++) );
     System.out.println("++d   = " +  (++d) );
  }`在这里插入代码片`
}

运行结果为

a + b = 30
a - b = -10
a * b = 200
b / a = 2
b % a = 0
c % a = 5
a++   = 10
a--   = 11
d++   = 25
++d   = 27

关系运算

public class Test {
 
  public static void main(String[] args) {
     int a = 10;
     int b = 20;
     System.out.println("a == b = " + (a == b) );
     System.out.println("a != b = " + (a != b) );
     System.out.println("a > b = " + (a > b) );
     System.out.println("a < b = " + (a < b) );
     System.out.println("b >= a = " + (b >= a) );
     System.out.println("b <= a = " + (b <= a) );
  }
}

运行结果为


```java
a == b = false
a != b = true
a > b = false
a < b = true
b >= a = true
b <= a = false

逻辑运算符

public class Test {
  public static void main(String[] args) {
     boolean a = true;
     boolean b = false;
     System.out.println("a && b = " + (a&&b));
     System.out.println("a || b = " + (a||b) );
     System.out.println("!(a && b) = " + !(a && b));
  }
}

``
运行结果

a && b = false
a || b = true
!(a && b) = true

赋值运算符

public class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int c = 0;
        c = a + b;
        System.out.println("c = a + b = " + c );
        c += a ;
        System.out.println("c += a  = " + c );
        c -= a ;
        System.out.println("c -= a = " + c );
        c *= a ;
        System.out.println("c *= a = " + c );
        a = 10;
        c = 15;
        c /= a ;
        System.out.println("c /= a = " + c );
        a = 10;
        c = 15;
        c %= a ;
        System.out.println("c %= a  = " + c );
        c <<= 2 ;
        System.out.println("c <<= 2 = " + c );
        c >>= 2 ;
        System.out.println("c >>= 2 = " + c );
        c >>= 2 ;
        System.out.println("c >>= 2 = " + c );
        c &= a ;
        System.out.println("c &= a  = " + c );
        c ^= a ;
        System.out.println("c ^= a   = " + c );
        c |= a ;
        System.out.println("c |= a   = " + c );
    }
}

运行结果为

c = a + b = 30
c += a  = 40
c -= a = 30
c *= a = 300
c /= a = 1
c %= a  = 5
c <<= 2 = 20
c >>= 2 = 5
c >>= 2 = 1
c &= a  = 0
c ^= a   = 10
c |= a   = 10

Java 循环结构

Java中有三种主要的循环结构:
while 循环
do…while 循环
for 循环

while 循环
while是最基本的循环,它的结构为:

while( 布尔表达式 ) {
  //循环内容
}

只要布尔表达式为 true,循环就会一直执行下去。
do…while 循环
do…while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次。

do {
       //代码语句
}while(布尔表达式);

如果布尔表达式的值为 true,则语句块一直执行,直到布尔表达式的值为 false。
for循环

for(初始化; 布尔表达式; 更新) {
    //代码语句
}

break 关键字
break 的用法很简单,就是循环结构中的一条语句:

break;

Java 条件语句

if 语句

if(布尔表达式)
{
   //如果布尔表达式为true将执行的语句
}

if…else语句

if(布尔表达式){
   //如果布尔表达式的值为true
}else{
   //如果布尔表达式的值为false
}

if…else if…else 语句

if(布尔表达式 1){
   //如果布尔表达式 1的值为true执行代码
}else if(布尔表达式 2){
   //如果布尔表达式 2的值为true执行代码
}else if(布尔表达式 3){
   //如果布尔表达式 3的值为true执行代码
}else {
   //如果以上布尔表达式都不为true执行代码
}

嵌套的 if…else 语句

if(布尔表达式 1){
   //如果布尔表达式 1的值为true执行代码
   if(布尔表达式 2){
      //如果布尔表达式 2的值为true执行代码
   }
}

Java switch case 语句

switch(expression){
    case value :
       //语句
       break; 
    case value :
       //语句
       break; 
    //可以有任意数量的case语句
    default : 
       //语句
}

Java 继承
继承的概念
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为

类的继承格式
class 父类 {
}

class 子类 extends 父类 {
}

Java反射

反射是一个很吸引人的特性,也是一个奇特的特性,之所以说它奇特,是因为Java提倡的是封装,而反射却可以破坏泛型、破坏封装,从而访问类的成员Reflection是Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性。例如,使用它能获得 Java 类中各成员的名称并显示出来。 Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。

Class类是一个特别的类,名字也有意思,可以叫做类类,它属于java.lang包,用来保存和记录某一个类的基因信息,如构造方法、方法、成员变量等等,在java程序运行过程中,每个类被加载都可以在内存中生成一个相应的Class对象:获取一个类的信息主要有3种方法–>

Class.forName():该方法可以通过类的全限定名来获得类名和接口名的信息,又称为强制性加载,既可以加载,又可以返回Class的对象;如:Class c1 = Class.forName(“Java.lang.util”)

getClass():该方法可以通过类的对象来获得类信息;如Class c = a.getClass()

还可以使用“类名.class”来返回该类的对象,这个类可以是任何数据类型的;如Class c = int.class

Class类中有一些常用的方法:

getName():获得Class对象对应类的名称

getDeclaredField(String):获取指定名称的成员变量对应的字段对象

getDeclaredFields():获取Class对象所对应类所声明的所有成员变量的数组

getFields():获取一个包含某些Field对象的数组

getDeclaredMethods():获取Class对象所对应类自己声明的所有方法的数组

newInstance():调用默认无参构造方法新建Class对象所表示的类的一个新对象

下面看一个简单的实例:

package test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class RelectTestA {
    public static void main(String[] args) {
        Class c = null;
        try {
            c = Class.forName("test.Animal");
            Object obj = c.newInstance();
            Constructor con = c.getDeclaredConstructor(String.class,int.class);
            Object obj2 = con.newInstance("maidou",8);
            Field f = c.getDeclaredField("name");
            f.setAccessible(true);
            String name = (String) f.get(obj2);
            System.out.println("obj2的名字是:"+name);
            f.set(obj2, "qizai");
            Method m = c.getDeclaredMethod("move", String.class);
            m.setAccessible(true);
            Object o = m.invoke(obj2, "上海");
        } catch (Exception e) {
            e.printStackTrace();
        }
                                                              
    }
}

输出一下:

call the method without parameters
call the method with parameters
obj2的名字是:maidou
qizai move to 上海

网络编程
网络编程初级

   首先来回忆一些计算机网络的知识吧,计算机网络按照不同的分类方式来划分,可以分为不同的类型:

*按照网络规模和范围可以简单划分为:局域网,城域网和广域网;

*按照网络的拓扑结构可以分为:星型网络、总线网络、环线网络、树型网络、星型环线网络等;

*按照网络的传输介质来划分:双绞线、同轴电缆、管道纤维和实现戒指等。

   OSI的7成网络模型为:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层;物理层和数据链路层是数据传输的基础层,通过网络层连接交换网络服务数据单元,在系统之间提供可靠的、透明的数据传送、提供端到端的错误回复和流的控制,提供两个进程间的连接管理功能,处理被传输数据的表示问题,完成数据转换、格式化和文本压缩、是直接面对用户的一层,提供OSI用户服务。

   在计算机网络中曾经学到了很多的协议,如ICMP,UDP, TCP/IP等等协议,具体协议内容可以看看计算机网络那本书,上面说的很详细,下面说一下TCP/IP协议:IP协议制保证计算机能发送和接受分组数据,而TCP协议则可以提供一个可靠的、可控制的信息流传输服务;TCP/IP协议是Internet尽可能成为一个分散、无序的网络,TCP/IP最早出现在UNIX系统中,现在几乎所有的厂商和操作系统都已经支持它了,同时,TCP/IP也是Internet的基础协议,其通常可以被看成一个4层模型:应用层、传输层、网络层以及链路层,可以与OSI的7层网络协议对比记忆。

   在网络中有几个十分重要的属性,即IP地址,子网掩码和端口号,IP地址,众所周知,用来在Internet中表示自己的计算机的位置,现在的IPV4是32位的,分为A类地址,B类地址以及C类地址,D、E等等保留的地址,以后IPV6会随着网卡的增多而被应用进来,因为其支持64位,所以对于以后几十年甚至几百年是够用了;一般来说子网掩码是相对于IP地址来划分的:如A类的为255.0.0.0,B类的为:255.255.0.0,C类的为:255.255.255.0;端口号:计算机的端口是计算机与外界交流的出入口,它包括硬件和软件两方面的涵义,硬件意义上的端口,有常称为接口,如某些进程会使用相应的端口,而软件意义上的端口,一般指网络中面向连接服务和无连接服务的通信协议端口,是一种抽象的数据结构。

有一个类专门用于代表一个IP地址,InetAddress:

InetAddress在java.net包中,它没有任何的构造器,可以通过它自身的静态方法来得到InetAddress类的实例:

package net;
importjava.net.InetAddress;
importjava.net.UnknownHostException;
public classHello {
      public static void main(String[] args)throws Exception {
           InetAddress ia;
           ia = InetAddress.getLocalHost();
           System.out.println(ia);
      }
}

输出了本机的IP地址:HXJ8Z1OJ7AS96JT/192.168.1.2
Socket:套接字Socket是指向基于网路的另一个应用成语的通信链的引用,应用程序通常通过“套接字”向网络发出请求或者应答网络请求,Socket大致位于OSI参考模型的会话层,而会话层负责控制和管理两台计算机之间的数据流交换。简而言之,一台计算机和另一台计算机进行对话的socket将会建立一个“连接通道”,我们可以使用这个通道在计算机之间交换数据。

下面介绍两个与Socket通信有关的类:java.net.ServerSocket/java.net.Socket,这两个类用于建立一个双向的通信,ServerSocket用于建立等待来自客户端访问的“服务器”,要建立一个Socket通信应用,首先需要建立一个服务器端的应用:

ServerSocket构造器:

ServerSocket():用于建立一个Socket,未绑定端口;

ServerSocket(intport):用指定的端口port来创建一个侦听Socket;

ServerSocket(intport,int backlog):加上一个用来改变连接队列长度的参数backlog;

ServerSocket(intport,int backlog,InetAddress localAddr):在机器存在多个IP地址的情况下,允许通过localAddr这个参数来指定侦听的IP地址

ServerSocket的方法:

Socket accept():用于接受一个客户机的连接,如果有客户机连接到ServerSocket所创建的侦听端口,则返回一个Socket实例,否则,将一直等待。

void close():关闭Socket连接。

   而Socket用于表示网络间的通信,Socket类:

Socket():建立一个没有连接的Socket;

Socket(InetAddressaddress,int port):建立一个指定主机IP地址address,端口port上的Socket连接;

Socket(String host,intport):建立一个指定主机名称host,端口port上的Socket连接;

Socket常用方法:

getInputStream():得到一个InputStream流,可以像使用任何其他数据流一样使用该对象;

getOutputStream():得到一个OutputSream流。

Socket通过getInputStream和getOutputStream来读写数据。

下面一个简单的服务器和客户端的程序:

   Server.java
package net;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.net.ServerSocket;
importjava.net.Socket;
public class Server {
       public static void main(String[] args){
              ServerSocket ss ;
              try {
                     System.out.println("I'mServer Port");
                     ss = newServerSocket(5560);
                     Socket s = ss.accept();
                     System.out.println("oneclient connected!");
                     BufferedReader br = newBufferedReader(new InputStreamReader(s.getInputStream()));
                     System.out.println(br.readLine());
                     br.close();
                     ss.close();
              } catch (IOException e) {
                     e.printStackTrace();
              }
       }
}

Client.java

package net;
importjava.io.BufferedWriter;
importjava.io.IOException;
importjava.io.OutputStreamWriter;
importjava.net.Socket;
importjava.net.UnknownHostException;
public class Client {
       public static void main(String[] args) {
              Socket s = null;
              try {
                     s = newSocket("localhost",5560);
                     System.out.println("connectedsuccessfully!");
                     BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(s.getOutputStream()));
                     bw.write("O NE");
                     bw.close();
                     s.close();
              } catch (UnknownHostException e) {
                     e.printStackTrace();
              } catch (IOException e) {
                     e.printStackTrace();
              }
       }
}
Server端控制台输出:
I'm Server Port
one clientconnected!
O N E
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值