首页 > 编程语言 > 详细

java基础(上)

时间:2020-05-09 00:08:16      阅读:58      评论:0      收藏:0      [点我收藏+]

java基本程序设计结构

 

javac 程序是一个java编译器 。可以将 . java 文件 编译层 .class 文件,并发送到java虚拟机。虚拟机执行编译器存放在class文件中的字节码。类名的命名规则:大写字母开头的名词;源代码的文件名必须与共有类名字相同,并以java作为扩展名。java是强类型语言,必须为每个变量声明一种类型。

数据类型

8种基本类型,4种整型,2种浮点型,一种用于表示Unicode编码的字符单元。int (4),short(2) ,long(8) ,byte(1)长整型数值后面有一个后缀L  。

C/C++ 中int表示的整型与目标机器相关,java中,所有整型所占据的字节数与平台无关。float(4)  ,  double(8)。float 类型的数值后面有一个后缀F,没有后缀的浮点数默认为double类型。


表示溢出和出错情况的三种特殊情况。

Double.POSITIVE_INFINITY

Double.NEGATIVE_INFINITY

Double.NaN


char类型用于表示单个字符。

boolean 在C++中,数值或指针可以代替boolean值,整数0相当于布尔值false,非0相当于true,java中不行。

C/C++中使用const 定义常量,java中使用final定义常量。

运算符

数学函数与常量

在Math类中,包含各种各样的数学函数。Math类中的方法不需要建立对象就可以使用,

double x = 4;
double y = Math.sqrt(x);
double y = Math.exp(y);
//表示π和e的进似值
Math.PI;
Math.E;

在源文件顶部加上:import static java.lang.Math.*

就可以不必再数学方法名等加前缀"Math."


枚举类型

有时变量的取值只在一个有限的集合内。可以自定义枚举类型,

enum Size{SMALL , MEDIUM , LARGE , EXTRA_LARGE}; 
Size s = Size.MEDIUM;

字符串

java没有内置的字符串类型,而是在标准java类库中提供一个预定义类String
String e = "" ;//an empty string

String greeting = "hello";

子串(从较大字符串提取一个子串)substring

String greeting = "hello";
String s = greeting.substring(0,3);
/*get "hell" ,复制greeting中的[0,3)给s

输入输出

读取输入:

Scanner in = new Scanner(System.in);
//构造一个Scanner对象,并与“标准输入流”关联
System.out.print("what is your name?");
String name = in.nextLine();
//nextLine 输入下一行
String firstname = in.next();
//读取一个单词,以空白符作为分隔符。
System.out.print("How old are you?");
int age = in.nextInt();
//读取一个整数

Scanner类定义在 java.util包中,如果当前使用的类不是定义在基本java.lang包中时,一定要使用import

如果要实现输入不可见,可以使用Console,想读取一个密码,可以采用

Console cons = System.console();
String username = cons.readLine ("User name:");
char[] passwd = cons.readPassword("Passwoed:");

文件输入输出

需要一个用Flie对象构造一个Scanner对象。

Scanner in = new Scanner(new File("myfile.txt"));
//文件如果有路径“c://document//computer//myfile.txt”

大数值

如果基本类型的整数和浮点数精度不能满足需求,可以使用java.math包中的BigInteger和BigDecimal

BigInteger类实现任意精度的整数运算,BigDecimal类实现任意精度的浮点数运算。

BigInteger a = BigInteger.valueOf(100);
//将普通的数值转换为大数值
BigInteger c = a.add(b); //c = a+b
BigInteger d = c.multiply(b.add(BigInteger.value(2)));//d = c*(b+2)

 


for each 循环、数组初始化和匿名数组

一旦创建数组,就不能再改变它的大小,如果需要经常在运行过程中扩展数组大小,就应该使用数组列表(array list)

int[] a = new int[100];
for(int e : a) //循环a中的每一个元素
{
 System.out.println(e);
}

匿名数组:

int[] smallPrimes = {2,3,4,5,6,7};
new int[] = {3,4,6,8,5,7};
smallPrime = new int[] {12,34, 56,3,4,5};  
//通过匿名数组实现在不创建新变量情况下重新初始化一个数组

数组拷贝

int[]  smallPrime ={2,4,6,5,3};
int[] luckynumbers = smallPrime;
//数组变量的拷贝
int[] copied = Arrays.copyOf(luckynumbers, luckynumbers.length);
//数组的拷贝
luckynumbers = Arrays.copyOf(luckynumbers , 2*luckynumbers.length);
//这个方法通常用来增加数组大小
?

 

对象与类

类、使用现有类、用户自定义类、静态域与静态方法、方法参数

在java中,任何对象变量的值都储存在另外一个地方的对象的引用。

方法可以访问所属类的私有特性,而不仅限于访问隐式参数的私有特性。


调用另一个构造器、初始化块、对象析构与 finalize 方法

将实例域定义为 Final ,构建对象时必须初始化这样的域,这个域的值在构造器执行后,必须设置,并且在后面的操作种,不能够再对他进行修改。

静态域与静态方法:

如果将域定义为 static ,每个类只有一个这样的域。而每个对象对于所有的实例域都有自己的一份拷贝。

静态常量

public class Math
{
public static final double PI = 3.141592657
}

静态方法

是一种不能向对象实施操作的方法,可以认为静态方法是没有this 参数的方法。

public static getNecId()
{
return nextId;
}
?

可以·通过类名调用这个方法

int n = Employee.getNextId();

使用静态方法的场景:

一个方法不需要访问对象状态,其所需参数都是通过显示参数提供

一个方法只需要访问类的静态域

参数的传递:

一个方法不可能修改一个基本数据类型(数字,布尔值)。而对象引用作为参数就不同了,可以容易。(方法得到的只是对象引用的拷贝,对象引用和其他拷贝同时引用同一个对象)

finalize 方法,将在垃圾回收器清除对象之前调用。在实际应用种,不要依赖于使用finalize 方法回收任何短缺的资源,因为很难知道这个方法什么时候能调用。


使用包的主要原因是 确保类名的唯一性。

import +包名

将类放入包中,package +包名


类设计技巧

一定将数据设计为私有

一定要对数据初始化

不要在类中使用过多的基本数据类型


 

继承

动态绑定、阻止继承、抽象类、受保护访问

关键字extends 表示继承,java中所有继承都是公有继承。

class Manager extends Employee
{
public double getSalary
{
   return salary + bonus;
    //Manager 类的getSalary方法不能直接访问超类的私有域,
    double baseSalary =  super.getSalary(); //调用超类
    return baseSalary + bonus;
}
}

java不支持多继承,

 


Object

Object类是java中所有的最终祖先,在java中每个类都是由它扩展而来的。但是并不需要这样写:class Employee extends Object

 


泛型数组列表

java中允许在运行时确定数组的大小

int actualSize = 10;
Employee[] staff = new Employee[catualSize];

ArrayList是一个采用类型参数 泛型类

new ArrayList<Employee>  (100) 分配数组列表


反射(能够分析类能力的程序)

反射使用的主要对象是工具构造者,而不是应用程序员。

 


继承设计技巧


 

接口

接口,对象克隆、回调

(描述类具有什么功能,而不给出每个功能的具体实现)

java语言利用接口机制来实现多继承的大部分功能。

通常需要下面2个步骤

将类声明为实现给定的接口(关键字 implements)

对接口中的所有方法进行定义

接口中不能包含实例域或静态方法,但却可以包含常量。

尽管每个类只能拥有一个超类,但却可以实现多个接口。

接口于抽象类

使用抽象类表示通用属性存在一个问题,每个类只能扩展一个类。但每个类可以实现多个接口。

C++ 允许一个类有多个超类,该特性称为多继承。java不支持多继承,java利用接口机制来实现多继承的大部分功能。

对象克隆:

如果创建一个对象的新的 copy ,它的最初状态于原来一样,但是以后将可以各自改变各自的状态,那就需要clone方法。

clone方法是Object类的一个protected方法,在用户编写的代码中不能直接调用它。如果对象中所有数据都属于数值或基本类型,这样拷贝域没有任何问题。但是如果对象中包含子对象的引用,拷贝的结构会使两个域引用同一个子对象,源对象与克隆对象共享这部信息。

默认的克隆操作是浅拷贝,没有克隆包含在对象中的内部对象。

在Object类中,clone方法被声明为proteced ,子类只能调用受保护的clone方法克隆它自己。

如果原始对象与浅拷贝克隆对象共享的子类对象是不可变的,将不会产生任何问题;更常见的情况是子对象可变,因此必须重新定义clone方法,以便实现克隆子对象的深拷贝。

即使clone的默认实现能够满足需求,也应该实现cloneable 接口,将clone 重定义为public 并调用super.clone()

class Employee implements Cloneable
{
public Employee clone() throw CloneNotSupportedException
{
    return (Employee)super.clone();
}  
}
//建立深拷贝
public Employee clone() throw CloneNotSupportedException
{
Employee cloned = (Employee) super.clone();
cloned.hireDay = (Date) hireDay.clone();
return cloned;
}

 


内部类

 

静态内部类

使用内部类只是为了把一个类隐藏在另一个类的内部,并不需内部类引用外部类对象。


代理


 

 

图形程序设计

如果只希望用java编写服务器端的应用程序,并且对GUI编程又不感兴趣,那么就可以跳过。

创建框架

在java中,顶层窗口(就是没有包含在其他窗口中的窗口)被称为框架(frame)。

swing 类位于javax.swing包中。包名javax表示这是一个java扩展包,而不是核心包。

绝大多数swing组件都是以"J"开头,例如,JButton 、 JFrame 等。如果忘记写“J”(Button 、Frame 属于AWT组件) ,程序仍可以编译运行,但将swing和AWT组件混合在一起使用会导致视觉和行为不一致。

 

//显示一个空框架
import javax.swing.*;
?
public class SimpleFrameTest
{
   public static main(String[] , args)
  {
       SimpleFrame frame = new SimpleFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       frame.setVisible(true);
  }
}
?
class SimpleFrame extends JFrame
{
   public static final int DEFAULT_WIDTH = 300;
   public static final int DEFAULT_HEIGHT =200;
   
   public SimpleFrame()
  {
       setSize(DEFAULT_WIDTH , DEFAULT_HEIGHT);
  }
}

每个swing程序中,有两点技术需要强调

  • 所有swing组件必须由事件调度线程进行配置,线程将鼠标点击和键盘敲击控制转移到用户接口组件,

EventQueue.invokelater(new Runnable()
                      {
                          public void run()
                          {
                              statement;
                          }
                      }              
      );
  • 定义一个用户关闭这个框架时的响应动作 feame.setDefaultOperation(JFrame.EXIT_ON_CLOSE);在包含多个框架的程序中,不能在用户关闭其中一个框架时就让程序退出。在默认情况下,用户关闭窗口时只是将框架隐藏起来,而程序并没有终止。为了显示框架,main方法需要调用框架的setvisible方法。

     

  • ~|

 

 

框架定位:

通过继承从JFrame的各个超类中继承的许多处理框架大小和位置的方法,可以改变框架外观。

  • setLocation 和setBounds方法用户设置框架位置。

  • setIconImage用于告诉窗口系统在标题栏、任务切换窗口等位置显示那个图标。

  • setTitle 用于改变标题栏的文字

  • setResizable利用一个boolean值确定框架的大小是否允许用户改变。

     

技术分享图片

 

 

部署应用程序

异常、日志、断言和调试

处理异常,异常处理的任务就是将控制权从错误产生的地方转移给能够处理这种情况的错误处理器。

传统的处理方式是返回一个特定的错误编码,调用这个方法的方法进行分析;但并不是任何情况都可以返回一个错误编码。

异常对象都是派送与Throwable 类的一个实例。其下面有两个分支

(Error,Exception)。

Error类层次结构描述了Java运行时系统内部错误和资源耗尽错误。

Exception 类分为两支,

(RuntimeException <由程序错误导致>,另一个分支包含其他异常<由于I/O错误问题导致>)

一个方法必须声明所有可能抛出的已检查异常 ,如果方法没有声明所有可能发生的已检查异常,编译器就会给出错误。

 

 

捕获异常 

想要捕获异常,必须设置try/catch语块。

try
{
   code;
   more code;
}
catch (Exception e)
{
   handler for this type;
}

如果在try语块中任何代码抛出一个在catch子句中说明的异常类,那么

  • 程序将跳过try语块的其余代码

  • 程序将执行catch子句中的处理器代码

如果在try语句块中的代码没有抛出任何异常类,那么程序将跳过catch子句。

 

Finally子句

当代码抛出一个异常时,就会终止方法中剩余代码的处理,并退出这个方法的执行。如果方法获得了一些本地资源,并只有这个方法自己知道,又如果这些资源在退出方法前必须被回收,那么就会产生资源回收问题。

InputStream in = ...
try
{
    try
  {
       code that might throw exception;
  }
finally
{
  in.clode();
}
}
catch (IOException)
{
   show error dialog
}

断言

断言机制允许在测试期间向代码中插入一些检查语句。当代码发布时,这些插入的检测语句会被自动移走。

assert df;
assert ds : fd;

如果结果为false ,则抛出一个AssertionError异常。

想要断言x是一个非负数值,只需要简单使用下面这条语句。

assert x>=0;

或者将x的实际值传递给AssertionError对象,从而可以在后面显示出来。

assert x>=0 : x;

 

启用和禁用断言

在默认情况下,断言是被禁用的。可以在运行程序时用-enableassertions 或 -ea 选项启用它:

java -eanableassertions MyApp

 

记录日志

可以方便程序员观察程序运行的操作过程。

基本日志 :

日志管理系统管理着一个名为Logger.global的默认日志记录器,可以用System.out替换它,并通过调用info方法记录日志信息:

Logger.global.info("File->open menu item selected");

 

集合

java类库中接口集合迭代器接口

在java类库中,集合的基本接口是Collection接口。

这个接口有两个基本方法:

public interface Collection<E>
{
   boolean add (E element);
   Iterator<E> iterator();
  ...
}

add方法用于向集合添加元素,返回值是boolean 。添加的元素改变了集合放回true,否则返回false.(集合不允许有重复接口)。

Itetator方法用于返回一个实现了Itetator接口的对象。使用迭代器可以依次访问集合中的对象。

 

迭代器接口

public interface Iterator<E>
{
   E next();
   boolean hasNext();
   void remove();
}

多线程

在一个单独的线程中执行一个任务的简单过程:

  • 将任务代码移到实现了Runnable 接口的类的run方法中。

  • public interface Runnable
    {
       void run();
    }
    ?
    class MyRunnable implement Runnable
    {
       public void run()
      {
           task code;
      }
    }
  • 创建一个类对象Runnable r = new MyRunnable();

  • 由Runnable创建一个Thread对象;Thread t = new Thread(r);

  • 启动线程:t.start();

中断线程

当一个线程调用interrupt方法时,线程中的中断状态将被置位。每个线程都应该不定时的检查这个标志,以判断线程是否终止。

要弄清楚中断状态是否被置为,首先调用Thread。currentThread方法获得当前线程,然后调用isInterrupted()

while(!Thread.current().isInterrupted() && more work )
{
   do more work;
}

线程的状态

  • 新生线程   new Thread(r);

  • 可运行线程 

  • 被阻塞的线程和等待线程

  • 被终止的线程

     

线程属性

  • 线程优先级

    void setPriority(int newPriority)
    static int MIN_PRIORITY (最小优先级为1)
    static int NORM_PRIORITY(默认优先级 5)
     

    线程的优先级时高度依赖系统的,当虚拟机依赖于宿主机平台的线程实现机制时,Java线程的优先级被映射到宿主机平台的优先级上。

  • 守护优先级

    t.SetDaemon(true);守护优先级的唯一用途是为其他线程提供服务。计时器就是一个例子,它定时发送信号给其他线程。当只剩下守护线程时,虚拟机就退出

  • 同步

    为避免多线程引发的对共享数据的讹误,需要进行同步存取。

    有两种机制防止代码块受并发访问的干扰。

    • synchronized关键字(提供了一个锁以及相关的“条件”)

      mylock.lock(); //获得锁
      try
      {
         critical section;
      }
      finally
      {
         mylock.unlock();
      }
      ?
      private lock mylock = new Reentrantlock();

      这一结构保证任何时候只有一个线程进入临界区。一旦一个线程封锁了锁对象,其他任何线程都无法通过lock语句。

    • 条件对象

      public void transfer(int from ,int to , int amount)
      {
         banklock.lock();
         try
        {
             while(accounts[from]< amount)
            {
                 //等待
            }
             //改变金额
        }
         finally
        {
             banklock.unlock();
        }
      }
      ?
      private lock banklock = new Reentrantlock();

      如果一个方法用synchronied 关键字声明,那么对象的锁将保护整个方法。

  • 监视器

    在不需要程序员考虑如何加锁的情况下,就可以保证多线程的安全性。

  • 死锁

    锁和条件不能解决线程中所有的问题。

  • 执行器

    newCachedThreadPool 方法用于创建一个线程池,空闲线程会被保留60秒

 

 

数据库编程

java能够为SQL访问提供一套“纯”javaAPI 。同时提供一个驱动管理器,以允许第三方驱动程序可以连接到特定的数据库。数据库供应商就可以提供自己的驱动程序,将其插入到驱动管理器中。这将成为一种向驱动管理器注册第三方程序的简单机制。

JDBC的典型用法:

  • 在传统的客户端/服务器模型中,通常是在服务器端部署数据库,而在客户端安装富GUI程序。

  • 在如今三层模型中,客户端不直接调用数据库,而是调用服务器上的中间件层,由中间件层完成数据库的查询操作。其优点是:将可视化表示从业务逻辑和原始数据中分离出来。我们可以在不同的客户端,如Java桌面应用、浏览器或移动App,来访问相同的数据和相同的业务规则。

JDBC配置

数据库URL:在连接数据库时,我们必须使用各种与数据库类型相关的参数,例如主机名、端口号和数据库名。

驱动程序JAR文件:(需要获得你所使用的数据库的驱动程序的JAR文件,在运行访问数据库的程序时,需要将驱动程序的JAR文件包含到类路径中)

启动数据库:

注册驱动器类

连接到数据库:

String url = "jdbc:....";
String username = "joquin";
String password = "secret";
Connection conn = DriveManager.getConnection(url , username ,password);
   

使用JDBC语句:

使用JDBC Statement 来执行SQL语句,若获得执行结果,以及处理错误。

Statement stat = conn.createStatement();
String command = "UPDATE Books "+"SET Price = Price - 5.00" +"WHERE Title NOT LIKE ‘%Introduction%‘ ";
stat.executeUpdate(command);

executeUpdate 方法既可以执行“INSERT ,UPDATE,DELETE”操作,也可以执行“CREAT TABLE , DROP TABLE” 之类的数据定义语句。但是,执行SELECT 查询时必须使用executeQuery 方法。该方法会放回一个ResultSet 类型的对象,可以通过它来每次一行地迭代遍历所有查询结果。

ResultSet  rs = stat.executeQuery("SELECT * FROM Books");

分析结果时通常使用如下循环语句:

while(rs.next())
{
  ....;
}

输入输出

  • 访问文件和目录

  • 以二进制格式和文本格式来读写数据

  • 正则表达式

在Java API 中,可以从其中读入一个字节序列的对象称为输入流,而可以向其中写入一个字节序列的对象称为输出流。

保存数据时,可以选择二进制格式或文本格式。

文本格式的I/O:需要考虑字符编码方式。在Java内部使用UTF-16编码方式 中。OutputStreamWriter 类将使用选定的字符编码方式,把Unicode码元输出流转换为字节流,而InputStreamReader类将包含字节(以某种字符编码方式表示的字符)的输入流转换为可以产生Unicode 码元的读入器。

写出文本输出

对于文本输出,可以使用PrintWriter 。这个类拥有以文本格式打印字符串和数字的方法。

PrintWriter out = new PrintWriter("employee.txt" , "UTF-8");
String name = "joquin";
double salary = 6000;
out.print(name);
out.print(‘ ‘);
out.println(salary);
//他把 joquin 6000写出到写出器out,之后这些字符将会被转换成字节并最终写入employee.txt中。

读入文本输入

String content = new String (Files.readAllBytes(path),charset);
List<String> lines = File.readAllLines(path, charset);
//将一个大文件一行一行地读入
try(Stream<String> lines = Files.lines(path,charset))
{
  ...
}

读写二进制数据:

 

 

XML

是一种非常有用的描述结构化信息的技术。

网络

连接到服务器

  • 使用telnet

  • 用java程序连接

    package socket;
    ?
    import java.io.*;
    import java.net.*;
    import java.util.*;
    ?
    public class SocketTest
    {
       public static void main(String[] args)
      {
           try(Socket s = new Socket("time-a.nist.gov",13)); Scanner in = new Scanner(s.getInputStream(),"UTF-8")
          {
               while(in.hasNextLone())
              {
                   String line = in.nextLine();
                   System.out.println(line);
              }
          }
           
      }
    }

    Socket(String host ,int port); 构建一个套接字,用于连接给定主机和端口。

    InputStream getInputStream(),

    OutputStream getOutputStream() 获取可以从套接字中读取数据的流,以及可以向套接字写出数据的流

     

套接字超时,调用setSoTimeout方法设置超时单位(毫秒)。

Socket s = new Socket(...);

s.setSoTimeout(1000);

构造器超时的解决办法

Socket s =new Socket();

s.connect(new InetSocketAddress(host,port) , timeout);

 

实现服务器

服务器套接字:

ServerSocket s =new ServerSocket(8189);用于建立一个负责监控端口8189的服务器。

Socket incoming = s.accept(); 用于告诉程序不停的等待,直到有客户端连接到这个端口,该方法就会返回一个表示连接已经建立的Socket对象,可以使用这个对象来得到输入流,输出流。

Input Stream inSream = incoming.getInputStream();

OutputStream outStream = incoming.getOutputStream();

void close(); 关闭套接字

 

为多个客户端服务

前面的简单客户端会拒绝多客户端连接,使得某个用户可能会因长时间连接服务而独占服务,可以运用线程解决问题。

while(true)
{
   Socket incoming = s.accept();
   Runnable r = new ThreadEchoHandler(incoming);
   
   Thread t = new Thread(r);
   t.start();
}

每一个连接都会启动一个新的线程,因此多个客户端就可以同时连接到服务器。

半关闭:允许套接字连接的一端可以终止其输出,同时仍旧可以接收来自另一端的数据。

例如我们在向服务器传输数据,但是一开始并不知道要传输多少数据。在向文件写数据时,我们只需要在数据写入后关闭文件即可。通过关闭一个套接字的输出流来表示发送给服务器的请求数据已经结束,但是必须保持输入流处于打开的状态。

try(Socket socket = new Socket(host,port))
{
   Scanner in = new Scanner(socket.getInputStream(),"UTF-8");
   PrintWriter writer = new PrintWriter(Socket.getOutputStream());
   //send request data;
   writer.print(..);
   writer.flush();
   socket,shutdownOutputStream();
   while(in.hasNext)
}

可中断套接字

 

java基础(上)

原文:https://www.cnblogs.com/lanjieduanxin/p/12853632.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!