热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

AndroidKotlin开发实例(HelloWorld!)及语法详解

这篇文章主要介绍了AndroidKotlin开发实例及语法详解的相关资料,需要的朋友可以参考下

Android Kotlin开发实例及语法详解

前言

Kotlin是一种在 Java虚拟机上执行的静态型别编程语言,它主要是由俄罗斯圣彼得堡的JetBrains开发团队所发展出来的编程语言。该语言有几个优势

1. 简洁
它大大减少你需要写的样板代码的数量。
2. 安全
避免空指针异常等整个类的错误。
3. 通用
构建服务器端程序、Android 应用程序或者在浏览器中运行的前端程序。
4. 互操作性
通过 100% Java 互操作性,利用 JVM 既有框架和库。

配置

在我们的AndroidStudio开发工具中,要想使用Kotlin这个优秀的开发语言,我们需要安装插件,直接在安装插件界面搜索Kotlin然后安装。之后再gradle文件增加如下配置

apply plugin:'kotlin-android'
apply plugin:'kotlin-android-extensions'

dependencies {
 compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}

项目gradle文件

buildscript {
 ext.kotlin_version = '1.1.1'
 repositories {
  jcenter()
 }
 dependencies {
  classpath 'com.android.tools.build:gradle:2.3.1'
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

  // NOTE: Do not place your application dependencies here; they belong
  // in the individual module build.gradle files
 }
}

完成上面的配置后,我们就可以愉快的玩耍了。

Kotlin示例

首先我们还和以前一样,创建一个Android项目,自动创建一个Activity之后我们再创建一个java类

public class MainActivity extends AppCompatActivity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
  setSupportActionBar(toolbar);

  FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
  fab.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
    Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
      .setAction("Action", null).show();
   }
  });
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.menu_main, menu);
  return true;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  // Handle action bar item clicks here. The action bar will
  // automatically handle clicks on the Home/Up button, so long
  // as you specify a parent activity in AndroidManifest.xml.
  int id = item.getItemId();

  //noinspection SimplifiableIfStatement
  if (id == R.id.action_settings) {
   return true;
  }

  return super.onOptionsItemSelected(item);
 }
}
public class Test {
 private static String str = null;

 public static void main(String[] args) {
  str = "Code4Android";
  System.out.println(str);
 }
}

那上面的代码如果用kotlin实现是什么样子呢。尽管现在我们还不能写出Kotlin代码,但是在安装插件后AS中提供了自动转换Kotlin代码的功能

这里写图片描述

转换后的Kotlin代码

class MainActivity : AppCompatActivity() {

 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_main)
  val toolbar = findViewById(R.id.toolbar) as Toolbar
  setSupportActionBar(toolbar)

  val fab = findViewById(R.id.fab) as FloatingActionButton
  fab.setOnClickListener { view ->
   Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
     .setAction("Action", null).show()
  }
 }

 override fun onCreateOptionsMenu(menu: Menu): Boolean {
  // Inflate the menu; this adds items to the action bar if it is present.
  menuInflater.inflate(R.menu.menu_main, menu)
  return true
 }

 override fun onOptionsItemSelected(item: MenuItem): Boolean {
  val id = item.itemId
  if (id == R.id.action_settings) {
   return true
  }
  return super.onOptionsItemSelected(item)
 }
}


object Test {
 private var str: String? = null

 @JvmStatic fun main(args: Array) {
  str = "Code4Android"
  println(str)
 }
}

注意:AS提供的java代码自动转换功能,我们不要轻易使用,更不要转化我们成熟的项目,如果需要就需要我们自己去重构实现。否则会有意向不到的事情等着你,毕竟转换不是那么智能。上面的代码只是让你先简单熟悉下Kotlin代码时什么样子的,接下来我们先去学习一下Kotlin的基本语法。相信很容易上手。

Hello World!

我们由一个简单的”Hello World!”输出程序开始。与新建java文件类似,如下图,我们选择Kotlin File/Class.创建一个Kotlin文件。

这里写图片描述

package com.learnrecord

/**
 *Created by Code4Android on 2017/4/21.
 */

var str: String = ""

fun main(args: Array) {
 str = "Hello World!"
 println(str)
}

上述代码就是简单的输出一个字符串“Hello World”,package 后面跟的是包名,我们看出了和java文件的区别,在包名后面没有以分号“;”结尾。在Kotlin语法中,语句结尾都不在有分号“;”。

在Kotlin中变量声明有两种类型,val修饰变量是只读变量即只能赋值一次,再次赋值时就会编译错误
,如果我们需要多次修改值就需要使用var。在上面的 var str: String = “”中,str是变量名,:String,表明该变量是String类型变量,后面就是赋值语句。我们也可以这样写var str= “”省略了生命变量类型,它可以根据赋的值而自动推断出类型。如果我们使用下面赋值语句str=null,发现null是不能赋值的,这就是Kotlin的特性,如果我们想赋值null,可以修改为 var str:String?=”“。
fun就是函数生命,而这个main函数就和我们java中的main方法一样,是程序执行的入口。println就是一个打印输出。

Kotlin声明类型

在Kotlin中有如下几种Number类型,他们都是继承自Number抽象类。

Float(32位),Double(64),Int(32),Byte(8),Short(16),Long(64,类型用大写L,如12L),Any(任意类型),数组类型Array 根据传入的泛型数据自动匹配类型,Kotlin还提供了指定类型的Array,如ByteArray,CharArray,ShortArray,IntArray,LongArray,FloatArray,DoubleArray,BooleanArray。在数组类型中都提供了get(index),set(index,value)及iterator()方法供我们使用。

 val iArray: IntArray = intArrayOf(1, 2, 3)
 val sArray: Array = Array(3, { i -> i.toString() })
 val anyArray: Array = arrayOf(1, "2", 3.0, 4.1f) // 可将类型进行混排放入同一个数组中
 val lArray: LOngArray= longArrayOf(1L, 2L, 3L)

函数

我们先来实现一个简单的数值求和的函数,通用实现方法如下

 fun sum(a: Int, b: Int): Int {
  return a + b
 }

传入两个Int型数值,sum是函数名,括号后面的:Int表示该函数返回Int的值,函数体中对两个数字相加并返回。在Kotlin中表达式也可以作为函数体,编译器可以推断出返回类型,可以简化为

 fun sum(a: Int, b: Int) = a + b

为了更好理解表达式可以作为函数体,我们可以创建一个函数获取两个数的最大值,如下:

 fun max1(a:Int,b:Int)=if (a>b) a else b

需要注意的是若if后有多个表达式,如下

 fun max1(a:Int,b:Int)= if (a > b) {
  println(a)
  a
 } else {
  println(b)
  //如果我们将println(b)放到b的下面,运行会返回kotlin.Unit为无类型,返回值总是最后一个表达式的返回值或值
  b
 }
 println(max1(1,3))

括号中的表达式顺序决定了返回的值及其类型。

如果我们的方法体仅仅是打印字符串,并不返回值则

 fun printInt(a: Int): Unit {
  println(a)
 }

Unit就类似我们java中的void,即没有返回值,此时我们可以省略

 fun printInt(a: Int) {
  println(a)
 }

对于函数体,方法或者类等和java一样也有一些修饰符,如下

  • abstract //抽象类标示
  • final //标示类不可继承,默认属性
  • enum //标示类为枚举
  • open //类可继承,类默认是final的
  • annotation //注解类
  • private //仅在同一个文件中可见
  • protected //同一个文件中或子类可见,不可修饰类
  • public //所有调用的地方都可见
  • internal //同一个模块中可见,若类不加修饰符,则默认为该修饰符,作用域为同一个应用的所有模块,起保护作用,防止模块外被调用。

操作符

直接上代码如下

 //操作符 shl 下面对Int和Long
 var a: Int = 4
 var shl: Int = a shl (1) //Java中的左移运算符 <<
 var shr: Int = a shr (1) //Java中的右移运算符 >>
 var ushr: Int = a ushr (3) //无符号右移,高位补0 >>>
 var and: Int = 2 and (4) //按位与操作 &
 var or: Int = 2 or (4) //按位或操作 |
 var xor: Int = 2 xor (6) //按位异或操作 ^
 print("\nshl:" + shl + "\nshr:" + shr + " \nushr:" + ushr + "\nand:" + and + "\nor:" + or + "\nxor:" + xor)

输出信息为

shl:8
shr:2 
ushr:0
and:0
or:6
xor:4

在上面的部分操作符可达到逻辑操作符, 当我们使用Boolean时,or() 相当于 ||,and() 相当于 &&, xor() 当操作符两边相反时为true,否则为false ,not()时取反。

数组遍历及控制语句

遍历数组

 fun forLoop(array: Array) {
  //第一种方式直接输出字符(类似java foreach)
  for (str in array) {
   println(str)
  }
  //Array提供了forEach函数
  array.forEach {
   println(it)
   }
  //array.indices是数组索引
  for (i in array.indices) {
   println(array[i])
  }
  //(类似javafor(int i=0;i

使用when判断类型

fun whenFun(obj: Any) {
  when (obj) {
   25 -> println("25")
   "Kotlin" -> println("Kotlin")
   !is String -> println("Not String")
   is Long -> println("Number is Long")
   else -> println("Nothing")
  }
 }

is 和java中instanceof是一个作用判断是否为某个类型。!is即判断不是某个类型。

//@定义label,一般用在内层循环中跳到外层循环:i in 0..2等价于java中 for(int i=0;i<=2;i++)效果
 loop@ for (i in 0..2) {
  for (j in 0..3) {
   println("i:" + i + " j:" + j)
   if (j == 2)
   //continue@loop//跳到外层循环,继续往下执行
    break@loop //跳到外层循环label处,跳出改层循环
  }
 }

倒序输出是downTo

 //倒序输出5 4 3 2 1 0
 for (i in 5 downTo 0) {
  println(i)
 }
 //设置输出数据步长
  for (i in 1..5 step 3) print(i) // 输出 14
  //step和downTo混合使用
  for (i in 5 downTo 1 step 3) print(i) //输出52

类与枚举

/*** constructor:构造函数
 * constructor无修饰符(如:private)时,constructor可以省略:
 * 当是无参构造函数时,整个构造函数部分也可以省略,省略的构造函数默认是public的
 * 由于primary constructor不能包含任何代码,因此使用 init 代码块对其初始化,
 * 同时可以在初始化代码块中使用构造函数的参数
 */
open class People private constructor(var id: String, var name: String) {
 //可以类中初始化属性:
 var customName = name.toUpperCase() //初始化属性
 //次构造函数,使用constructor前缀声明,且必须调用primary constructor,使用this关键字
 constructor( id: String, name: String, age: Int) : this(id, name) {
  println("constructor")
 }
 init {
  println("初始化操作,可使用constructor参数")
 }
 //需要open修饰,子类才可以
 open fun study() {
  print("study")
 }
 //People前的冒号":"是继承的意思,实现类接口的时候也是冒号
class Student(id: String, name: String) : People(id, name) {
 var test: Number = 3
 private var name1: String&#63;
  get() {
   return name1
  }
  set(value) {
   name1 = value
  }
 //override修饰的方法,默认是可以被继承的。若希望不被继承,可以使用 final 关键词修饰
 override fun study() {
  super.study()
 }
}

}

数据类用来保存数据,类似于POJO类,使用data关键词进行定义,编译器默认会为数据类生成以下四个方法

  • equals()
  • hashCode()
  • toString()
  • copy()

通过数据类你会看到Kotlin的简洁性,我们创建一个Staff类,有String类型的name,position和泛型T(使用泛型仅仅是为了在Kotlin中接触以下泛型)

java实现代码:

public class StaffJ {
 private String name;
 private String position;
 private T age;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getPosition() {
  return position;
 }

 public void setPosition(String position) {
  this.position = position;
 }
 public T getAge() {
  return age;
 }
 public void setAge(T age) {
  this.age = age;
 }
}

Kotlin数据类:

data class Staff(var name: String, val position: String,var age:T)

通过对比我们就看出了优点了,一行代码就实现了,具体使用

 var staff = Staff("code4Android","Android工程师","22") //实例化对象

要获取某个属性如获取名字staff.name,赋值就是staff.name=”code4Android2”,既然说了这样可以赋值,但是动手的小伙伴说为什么我敲的报错啊,如下

 staff.position="前端"

编译报错了,在前面我们说过val修饰的属性只能赋值一次,那在这里val修饰的属性我们是不能再次赋值的。

fun main(arg:Array){
 var staff = Staff("code4Android","Android工程师","22") //实例化对象
 staff.name="code4Android2"
 var staff1=staff.copy()
 //使用copy的时候可以指定默认值,可以指定任意个用逗号","隔开
 var staff2=staff.copy(name="ccc",position = "kotlin")
 println("name:${staff2.name} position:${staff2.position} age ${staff2.age}")
 //staff.position="Kotiln" //val不能再次赋值
 var anotherStaff= Staff("code4Android","Android工程师",22) //实例化对象

 println("staff toString(): ${staff.toString()} anotherStaff toString(): ${anotherStaff.toString()}")
 println("staff hashCode(): ${staff.hashCode()} anotherStaff hashCode(): ${anotherStaff.hashCode()}")
 println("staff is equals another staff &#63; ${staff.equals(anotherStaff)}")
}

上面使用了字符模板,在Kotlin中有两种字符模板形式,$<变量>、${<变量>}

 var name:String="Code4Android"
 println("我的名字叫$name")
 println("我的名字叫${name}")

/**
 * java允许使用匿名内部类;kotlin也有类似的概念,称为对象表达式-object expressions
 */
open class KeyBord{
 open fun onKeyEvent(code:Int):Unit = Unit
}

 
/**匿名内部类**/
var key=object :KeyBord(){
 override open fun onKeyEvent(code:Int):Unit = Unit
}

枚举

enum class Color{
 RED,BLACK,BLUE,GREEN,WHITE
}
fun display(){
 var color:Color=Color.BLACK
 Color.valueOf("BLACK") // 转换指定name为枚举值,若未匹配成功,会抛出IllegalArgumentException
 Color.values() //已数组的形式,返回枚举值
 println(color.name)////获取枚举名称
 println(color.ordinal)//获取枚举值在所有枚举数组中定义的顺序,0开始
}

在Kotlin中枚举还支持方法。

扩展

/**
 * fun receiverType.functionName(params){
 *body
 *}
 * receiverType : 待扩展的类名
 * .   :修饰符为扩展符
 * functionName :为自定义的扩展函数名,
 * params  :为自定义的扩展函数参数,可为空
 * 扩展函数作用域,受函数的visibility modifiers影响
 * 扩展函数并没有对原类做修改,而是为被扩展类的对象添加新的函数。
 * 有一条规则,若扩展函数和类原有函数一致,则使用该函数时,会优先使用类本身的函数。
 */
class Employee(var name: String) {
 fun print() {
  println("Employee")
 }
}

//扩展函数
fun Employee.println() {
 print("println:Employee name is $name")
}


/**
 * 可以扩展一个空对象
 */
fun Any&#63;.toString1(): String {
 if (this == null)
  return "toString1:null"
 else {
  return "toString1" + toString()
 }
}

/**
 * 扩展属性
 * 由于扩展属性实际上不会向类添加新的成员,
 * 因此无法让一个扩展属性拥有一个后端域变量. 所以,对于扩展属性不允许存在初始化器.
 * 扩展属性的行为只能通过明确给定的取值方法与设值方法来定义,也就意味着扩展属性只
 * 能被声明为val而不能被声明为var.如果强制声明为var,即使进行了初始化,
 * 在运行也会报异常错误,提示该属性没有后端域变量。
 */
val Employee.lastName: String
 get() {
  return "get:"+name
 }

使用

fun main(arg: Array) {
 var employee = Employee("Code4Android")
 employee.print()
 employee.println()
 println(employee.toString1())
 println(employee.lastName)
}

代理

**
 * 被代理接口
 */
interface Base {
 fun display()
}

/**
 * 被代理类
 */
open class BaseImpl : Base {
 override fun display() = print("just display me.")
}

/**
 * 代理类,使用:以及关键词by进行声明
 * 许代理属性和其他继承属性共用
 * class Drived(base: Base) : Base by base,BaseImpl()
 */
class Drived(base: Base) : Base by base

//使用
fun show() {
 var b = BaseImpl()
 var drived = Drived(b)
 drived.display()

}

**
 * 代理类型:
 * 懒加载:Lazy
 * 观察者:Delegates.observable()
 * 非空属性:Delegates.notNull<>()
 */
class Water {

 public var weight:Int by Delegates.notNull()
 /**
  * 代理属性
  */
 public val name: String by lazy {
  println("Lazy.......")
  "Code4Android"
 }
 public var value: String by Delegates.observable("init value") {
  d, old, new ->
  println("$d-->$old->$new")
 }
}

fun main(arg: Array) {
 show()
 var water = Water()
 println(water.name)
 println(water.name)
 water.value = "11111"
 water.value = "22222"
 water.value = "33333"
 println(water.value)
 println(water.value)
 //必须先赋值否则IllegalStateException: Property weight should be initialized before get.
 water.weight=2
 print(water.weight)
}

操作符::

val String.lastChar: Char
 get() = this[this.length - 1]

class A(val p: Int)

 //1,反射得到运行时的类引用:
 val c = Student::class
 //2,函数引用
 fun isOdd(x: Int) = x % 2 != 0
 val numbers = listOf(1, 2, 3)
 println(numbers.filter(::isOdd)) 

 //3,属性引用(在此引用main函数主体外声明的变量)
 println(::x.get())
 ::x.set(2)
 println(x)
 //4,::x 表达式评估为 KProperty 类型的属性,它允许我们使用 get() 读它的值或者使用名字取回它的属性
 val prop = A::p
 println(prop.get(A(1))) 

 //5,对于扩展属性
 println(String::lastChar.get("abc")) 

 //6,与 java 反射调用
 println(A::p.javaClass),
 var f: Array = A::p.javaClass.declaredFields

伴生对象

伴生对象(companion object )类似于java中的静态关键字static。在Kotlin没有这个关键字,而是伴生对象,具体用法

open class People constructor(var id: String, var name: String){
 //可以类中初始化属性:
 var customName = name.toUpperCase() //初始化属性

 //使用constructor前缀声明,且必须调用primary constructor,使用this关键字
 constructor( id: String, name: String, age: Int) : this(id, name) {
  println("constructor")
 }

 init {
  println("初始化操作,可使用constructor参数")
 }
 //,Kotlin的class并不支持static变量,所以需要使用companion object来声明static变量,
 // 其实这个platformStatic变量也不是真正的static变量,而是一个伴生对象,
 companion object {
  val ID = 1
 }
}

使用的话直接People.ID。

单例模式

在Kotlin中使用object修饰类的时候,。该类是单例对象。

/**
 * 使用object定义类,该类的实例即为单例,访问单例直接使用类名,不能通过构造函数进行访问,不允许有构造函数
 * Place.doSomething() // 访问单例对象
 */
object Singleton {
 fun doSomething() {
  println("doSomething")
 }
}


/**
 * 实例化的时候,单例是懒加载,当使用的时候才去加载;而对象表达式是在初始化的地方去加载。
 *
 * 当在类内部使用 object 关键词定义对象时,允许直接通过外部类的类名访问内部对象进而访问其相关属性和方法,相当于静态变量
 * 可以使用companion修饰单例,则访问其属性或方法时,允许省略单例名
 * MyClass.doSomething() // 访问内部单例对象方法
 */
class MyClass {
 companion object Singleton {
  fun doSomething() {
   println("doSomething")
  }
 }
}

 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

源码下载:http://xiazai.jb51.net/201705/yuanma/KotlinForAndroid(jb51.net).rar


推荐阅读
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 本文详细介绍了云服务器API接口的概念和作用,以及如何使用API接口管理云上资源和开发应用程序。通过创建实例API、调整实例配置API、关闭实例API和退还实例API等功能,可以实现云服务器的创建、配置修改和销毁等操作。对于想要学习云服务器API接口的人来说,本文提供了详细的入门指南和使用方法。如果想进一步了解相关知识或阅读更多相关文章,请关注编程笔记行业资讯频道。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
author-avatar
xinyaolin_857
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有