Обекти в Java

Декларация

Java е чисто обектно-ориентиран език. Класовете могат да се разглеждат като модули изграждащи Java програмите.
    клас =>  методи + член променливи
Класовете се използват за създаване на променливи, които са псевдоними на обекти (objets ,instances). Обектите представляват конкретна реализация на структурата на класа. 

Декларация на клас:
 
public class Person {
    public String name = "namePers";
    public int age;
    public Person(){
        name = "name1";
        age = 21;
    }
    public void growUp(int years) {
        age += years;
    }
}
две променливи  - name и age;
един метод – growUp() с параметър цяло число, без да връща резултат (void)
един конструктор - метод без тип, с името на класа за инициализация на променливите

 

Декларацията на променливите и методите, може да се извърши в произволен ред
 

Обекти, конструктор


За да се създадат променливи (instances) от клас Person:

    Person p1, p2;

Всеки език има свои собствени средства за манипулиране на данните. В  Java променливите от даден клас представляват псевдоними на обекти. Образно обектът може да се представи като телевизор а псевдонимът - като телеуправлението му. p1 и p2 от класа Person представляват променливи които са псевдоними на обекти от тип Person но обектите не са още създадени и променливите са "празни" - не сочат към реални обекти. За да могат да се използуват трябва динамично да се създадат обекти в специална част на паметта наречена  "heap", като се използва ключовата дума new и конструктора на класа:

    p1 = new Person();
    p2 = new Person(); 

Пример :

public class Test {
    public static void main (String[] arg){
        Person p1;
        p1 = new Person(19);
        Person p2 = new Person(34);
        p2.growUp(4);
        System.out.println("p1.age: "+p1.age);
        System.out.println("p2.age: "+p2.age);
    }
}
 
 

Достъп до член-данните

Когато обектът е създаден, достъпът до неговите член-данни става посредством операция '.' :

    p2.age = 21;
    p1.growUp();

Всеки обект притежава свое собствено копие от член-данните.

Както и член-данните, методите също са асоциирани с обекта. Но всеки обект не притежава свое собствено копие на методите. Всъщност съществува само една съвкупност от методи, но те работят с данните на даден обект.

За да се реализира този подход, всеки метод (с изключение на статичните методи) получава един имплицитен, скрит параметър, който представлява псевдоним на обекта, с който се работи и който се добавя автоматично всеки път, когато се използува някоя член-променлива. Така например инструкцията:

    age++;

се реализира като:

    (this.age)++;

Параметъра this е достъпен и може да се използва явно в тялото на на метода.
 

Инициализация на обектите

Не инициализираните променливи представляват една от главните причини за  "bugs" в една програма. Java (както и C++) въвеждат един специален метод наричан "конструктор", който се стартира всеки път по време на създаването на обект. Този метод:
   -  Има за цел инициализирането на член-данните;
   - Името му е идентично с името на класа
   - Няма тип, т.е. няма резултат изчислен след изпълнението (дори и "void").;

    - Съществува подразбиращ се конструктор.


Инициализацията на всеки обект минава през четири етапа:
    1)Резервиране на необходимата памет в "heap" за член-данните;
    2)Всички член-променливи се инициализират със стойност 0;
    3)Член променливите се променят съгласно стойностите декларирани в декларацията на класа;
    4)Стартира се конструктора, ако такъв е създаден за завършване на инициализацията на класа

Присвояването между два обекта има за резултат два псевдонима, които сочат върху един и същи обект:

class Number {
        int i;
}

public class Assignment {
        public static void main(String[] args) {
                Number n1 = new Number();
                Number n2 = new Number();
                n1.i = 9;
                n2.i = 47;
                System.out.println("1: n1.i: " + n1.i +", n2.i: " + n2.i);
                n1 = n2;
                System.out.println("2: n1.i: " + n1.i + ", n2.i: " + n2.i);
                n1.i = 27;
                System.out.println("3: n1.i: " + n1.i + ", n2.i: " + n2.i);
        }
}

Резултат:

        1: n1.i: 9, n2.i: 47
        2: n1.i: 47, n2.i: 47
        3: n1.i: 27, n2.i: 27

Релационните оператори '= =' et '!=' се отнасят не до обектите, а до техните псевдоними:

public class Equivalence {
        public static void main(String[] args) {
                Integer n1 = new Integer(47);
                Integer n2 = new Integer(47);
                System.out.println(n1 == n2); //сравнява псевдонимите - false
                System.out.println(n1 != n2); //сравнява псевдонимите - true
        }
}

За сравняване на самите обекти се използва методът equals() (за нови класове трябва да се предефинира, в противен случай отново сравнява псевдоними) !

System.out.println(n1.equals(n2)); //сравнява обектите - true 

Класове - обвивки(wrapper classes)

На всеки примитивен тип съответства един клас -обвивка  ("wrapper class"), който позволява създаването на обекти съответстващи на примитивния тип:

        char c = 'd';
        Character C = new Character(c);

или

    Character C = new Character('d');

Java 1.1 добави два класа за аритметика с висока точност – BigInteger и BigDecimal.
 
 

type primitif
wrapper class
boolean
Boolean
char
Character
byte
Byte
short
Short
int
Integer
long
Long
float
Float
double
Double
void
Void
-
BigInteger
-
BigDecimal

 
пример резултат
import java.math.BigInteger; 
public class WrappedClassApp {
   static final int radix = 16;
   public static void main(String args[]) {
      Boolean b1 = new Boolean("TRUE");
      Boolean b2 = new Boolean("FALSE");
      System.out.println(b1.toString()+" or "+b2.toString());
      for(int j=0;j<radix;++j)
           System.out.print(Character.forDigit(j,radix));
      System.out.println();
      System.out.print("Radix between "+ Character.MIN_RADIX);
      System.out.println(" and " + Character.MAX_RADIX);
      Integer i = new Integer(Integer.parseInt("ef",radix));
      Long l = new Long(Long.parseLong("abcd",radix));
      long m=l.longValue()*i.longValue();
      System.out.println("radix=4: "+Long.toString(m,4));
      System.out.println("radix=10: "+Long.toString(m,10));
      System.out.println("radix=16: "+Long.toString(m,16)); 
      System.out.println(Float.MIN_VALUE);
      System.out.println(Double.MAX_VALUE);

      BigInteger n=new BigInteger("1000000000000");
      BigInteger one=new BigInteger("1");
      while(!n.isProbablePrime(7)) n=n.add(one);
      System.out.println("\n"+n.toString(10)+" is probably prime.");
      System.out.println("It is "+n.bitLength()+" bits in length.");}
}

true or false
0123456789abcdef
Radix between 2 and 36
radix=4: 220012101203
radix=10: 10511459
radix=16: a06463
1.4E-45
1.7976931348623157E308

1000000000039 is probably prime.
It is 40 bits in length.

Модификатори на достъпа

Във вътрешността на даден клас всички негови член-компоненти - данни и методи са достъпни непосредствено чрез тяхното име.

Достъпът до член-данните и методите от методи извън класа зависи от модификаторите за достъп. Модификаторите дефинират различни нива на достъп до компонентите на класа. Задават се преди типа на компонентата. Съществуват четири модификатори за достъп:
    по подразбиране (без модификатор),
    public, 
   
protected, 
    private

по подразбиране (без модификатор): видим е само от класовете от същия пакет (директория):

public: компонентата е видима за всички без значение дали са вътре вътре или извън класа:

protected: компонентата е видима само за класовете от същия пакет и за производните му класове от други пакети.

private: компонентите са видими само за методите на класа (директен достъп). 


Modifier

class

package

subclass

world

public

X

X

X

X

protected

X

X

X

 

no modifier

X

X

 

 

private

X

 

 

 

  

Препоръка: Винаги се избира най-ограниченaта възможна видимост, с изключение на константите.


 

Статични членове

class Exemple {

        int m3=1;
        static int m2=3;
        static void func() {
                Exemple e1 = new Exemple();
                Exemple e2 = new Exemple();
                int k = m2; //  директен достъп
                int n = e1.m3; //  достъп чрез псевдоним на обект
                …
        }…
}


 

При декларирането на статична член компонента (static), за нея се заделя памет еднократно, независимо от броя на създаваните обекти.

Всички обекти от класа ползват един същи статичен член. Статичните функции не получават  this като параметър, следователно те нямат директен достъп до не статичните компоненти на класа. За достъп до тези компоненти в този случай трябва да се използуват псевдонимите на обектите.

Модификатори final, synchronized и native

final: sспецифицира, че член-променливата има константна стойност (инициализирана в момента на декларацията) или че методът не може да бъде предефиниран в производен клас. С други думи  final показва, че компонентът е дефиниран във своята окончателна версия.

synchronized: специфицира, че методът е "mono-thread". Синхронизираният метод допуска един единствен thread в даден момент. 

native: специфицира, че методът е реализиран на en C и се намира в изпълним файл. Методът има само декларация, не и дефиниция:

        native int Cprogramme();

Масиви

Декларирането на масив се извършва чрез средни скоби:

        int nombre[ ];
        long grille [ ], jours [ ];

За разлика от C, масивите в езика Java предствляват обекти от клас масив. Тези декларации въвеждат само псевдоними на масиви и не резервират никаква памет за масива, следователно декларациите не позволяват въвеждането въвеждането на броя на елемнтите. За да се резервира място за масива трябва или да се използва оператора new:

        int nombre[ ] = new int[10]; // масив от 10 цели числа

или да се присвои една последователност от елементи в момента на създаване на масива:

        char vowel[ ] = {'a', 'e', 'i', 'o', 'u'}; // масив от 5 елемента

Размерът на всеки масив се съхранява в една public член-променлива с име length:

        int longueur = vowel.length; //longueur = 5

Опитът да се достигне до несъществуващ елемент на масива генерира изключение  ArrayIndexOutOfBoundsException от тип RuntimeException.

Методът arraycopy() от клас System се използва за копиране на определен брой елементи от един масив в друг:

        System.arraycopy (objectsSource, positionSource, objectDestination, positionDestination, length)

Например за да се добави един елемент към масива vowel:

        char vowel[ ] = {'a', 'e', 'i', 'o', 'u'};
        char tmp[ ] = new char[vowel.length+1];
        System.arraycopy(vowel, 0, tmp, 0, vowel.length);
        tmp[vowel.lemgth] = 'y';
        vowel=tmp;

След операцията старият обект не е сочен от нито един псевдоним и ще бъде прибран от garbage collector.

Обхождане на масиви

За цялостно или частично обхождане на масива трябва да се използва цикъл - например  for. Следващия пример прави пълен обход на масив за показването му на конзолата.:

 

public class Array{ 
   public static void main(String a[]){ 
      int ar[] = {-3,4,-17,2,-1,8};
      for(int i =0; i< ar.length;i++){
           System.out.println("   "+ar[i]); 
      }
  
}
-3  4  -17  2   -1  8

Първият индекс на таблото 0, последният - ar.length-1.

Вариант на цикъл for  

Java 5.0 предлага нов цикъл  for, който позволява лесно цялостно обхождане на всички елементи на дадена колекция от обекти

for (<type>  <variable_name> : <collection>)
{

        // for body
}

public class Array{ 
   public static void main(String a[]){ 
      int ar[] = {-3,4,-17,2,-1,8};
      for(int el :ar){
           System.out.println("   "+el); 
      }
  
}
-3  4  -17  2   -1  8


Java решава въпроса с многомерни масиви чрез обекти, които представляват масиви от други масиви. 

Синтаксисът е подобен на този на С:

public class Matrix {
    public static void main(String arg[]){
        int matrix[][] = new int[3][6];
        for(int i =0;i<matrix.length;i++ ){                     // matrix.length - броят на елементите (линиите) в масива
            for (int j=0;j<matrix[i].length;j++){              //matrix[i].length - броят на елементите (числата) в  линия i на масива
                System.out.print("\t"+matrix[i][j]);
            }
            System.out.println();
        }
    }
}  

public class Matrix {
    public static void main(String arg[]){
        int matrix[][] = new int[3][6];
        for(int line[]:matrix ){                     // for ... each
            for (int k : line){                     //for … each
                System.out.print("\t"+k);
            }
            System.out.println();
        }
        matrix[0][0]=3;
        matrix[0][1]=5;
    }
}  

с инициализация      

public class Matrix1 {
    public static void main(String arg[]){
        int matrix[][] = {{1,2*3,7},{6,8,9}};
        for(int line[]:matrix ){
            for (int k : line){
                System.out.print("\t"+k);
            }
            System.out.println();
        }
    }
}

Възможно е създаването на двумерни масиви, редовете на които са с различна дължина:

public class Tabl {
    public static void main(String arg[]){
        int ex[][] = new int[3][ ];
        ex[0] = new int [3];
        ex[1] = new int[5];
        ex[2] = new int[4];
        for(int line[]:ex ){
            for (int k : line){
                System.out.print("\t"+k);
            }
            System.out.println();
        }
    }
}

с инициализация       

public class Tabl1 {
    public static void main(String arg[]){
        int ex[][] = {{1,2,3},{4,5,6,7},{8,9}};
        for(int line[]:ex ){
            for (int k : line){
                System.out.print("\t"+k);
            }
            System.out.println();
        }
    }
}
 
 Референциите към линиите могат да се променят при изпълнение на програмата

public class Tab_ir {
    public static void main(String arg[]){
        int tab[][] = new int[3][2];
        prt(tab);
        tab[1] = new int [4];
        prt(tab);
    }
    public static void prt(int tab[][]){
        System.out.println("\ntab:");
        for(int line[]:tab ){
            for (int k : line){
                System.out.print("\t"+k);
            }
            System.out.println();
        }       
    }
}

Пример
 
public class Array{ 
   public static void main(String a[]){ 
      int ar[][] = {{3,4},{17,2,1,8}}; 
      for(int i =0; i< ar.length;i++){ 
         for(int j = 0;j< ar[i].length; j++) System.out.print(" "+ar[i][j]); 
         System.out.println(); 
     
  
}
3 4 
17 2 1 8 


Вариант на цикъл for  


public class Array_s {
       public static void main(String a[]){
              String ar[][] = {{"Koko","Kiko","Kako"},{"Simo", "Sima"}};
              for(String[] line :ar){
                  for(String el:line)
                   System.out.print("   "+el);
                  System.out.println();
              }
           }
}
   Koko   Kiko   Kako
   Simo   Sima

Масив от обекти

class Birthday
public class Birthday {
    private int day,month,year;
    public Birthday(int d, int m, int y){
        this.day = d;
        this.month=m;
        this.year = y;
    }
    public String toString(){
        return "("+day+","+month+","+year+")";
    }
}

Birthday tab[] = new Birthday[2];

tab[0] = new Birthday(7, 7, 1980);
tab[1] = new Birthday(20, 12, 1984);

public class Tab {
    public static void main(String arg[]){
        Birthday bd[][]=new Birthday[3][4];
        init(bd);
        for(Birthday line[]:bd ){
            for (Birthday k : line){
                System.out.print("\t"+k);
            }
            System.out.println();
        }
    }
    public static void init(Birthday tb[][]){
        for(int i=0;i<tb.length;i++){
            for(int j =0; j<tb[i].length;j++){
                tb[i][j]=new Birthday((int)(Math.random()*30+1),
                        (int)(Math.random()*12+1),
                        (int)(Math.random()*100+1930));
            }
        }
    }
}

Lists

Подредена последователност от обекти от един и същи тип като за разлика от масива елементите могат да се увеличават или намаляват.
A Java List collection can only hold objects. 
List е interface, - не може да се създаде инстанциира директно . Два класа  ArrayList и  LinkedList.  Най-използвана  ArrayList. Постоянно време за достъп и може да се използва  System.arraycopy.
     

            List<Object> listOfObjects = new ArrayList<Object>();

Формален тип
<Object>  - може да съхранява всякакви обекти

Може и да се ограничи типа на съхраняваните елементъ

        class Person{
            ...
        }
        class Student extends Person{
            ...
        }
        List<Person> listOfPersons = new ArrayList<Person>();

Може да сухранява обекти  само от Person и от производните му класове - наприемер  Student.

Използване

вмъкване в  List

брой елементи.
Достъп до елементи
Изваждане.
Пример:
import java.util.*;
public class ListDemo {
   public static void main(String args[]) {
      // Create an array list
      ArrayList <String>  al = new ArrayList <String>();
      System.out.println("initial size:"+al.size());
      // add elements to the array list
      al.add("C");
      al.add("A");
      al.add("E");
      al.add("B");
      al.add("D");
      al.add("F");
      System.out.println("the new size:"+al.size());
      for(int i = 0; i <al.size(); i++){
         System.out.println(al.get(i));
      }
     String ex = al.remove (2);
     System.out.println("removing value:"+ex);
     System.out.println("size after remove:"+al.size());
     for(int i = 0; i <al.size(); i++){
         System.out.println(al.get(i));
     }
   }
}
initial size:0
the new size:6
C
A
E
B
D
F
removing value:E
size after remove:5
C
A
B
D
F

Итератори


 Итераторът е обект, който позволява обхождането на колекции.  Iterator получен чрез List's iterator операция връща елементи в една посока. Има и по-богат итератор - ListIterator, които позволява обхождането в двете посоки, промяна на елементите и справка за текущата позиция на итератора.
Създаване
        ListIterator<Type> it = list.listIterator();
        ListIterator<Type> it = list.listIterator(int)   

Първият конструктор позиционира в началото, вторият - на специфицирана позиция. Индексът сочи елемента, който ще бъде върнат с  next. 



Примери

import java.util.*;
public class IteratorDem {
    public static void main(String arg[]){
        // Create an array list
          ArrayList <String>  al = new ArrayList <String>();
          // add elements to the array list
          al.add("C");
          al.add("A");
          System.out.println("ArrayList:"+al.get(0)+" "+al.get(1));
         
          ListIterator<String> litr = al.listIterator();
         // litr.set("new");             error- there is no element in the iterator
         
         
          System.out.println("before element "+litr.nextIndex());
          System.out.println("after element "+litr.previousIndex());
         
          System.out.println(litr.next());
          System.out.println("before element "+litr.nextIndex());
          System.out.println("after element "+litr.previousIndex());
         
          litr.set("modified");     // modify the last element returned
                                          // by next() or previous()
          System.out.println("ArrayList:"+al.get(0)+" "+al.get(1));
         
    }
}
ArrayList:C A
before element 0
after element -1
C
before element 1
after element 0
ArrayList:modified A


import java.util.*;
public class IteratorDemo {
   public static void main(String args[]) {
      // Create an array list
      ArrayList <String>  al = new ArrayList <String>();
      // add elements to the array list
      al.add("C");
      al.add("A");
      al.add("E");
      al.add("B");
      al.add("D");
      al.add("F");

      // Use iterator to display contents of al
      System.out.print("Original contents of al: ");
      Iterator<String> itr = al.iterator();
      while(itr.hasNext()) {
         String element = itr.next();
         System.out.print(element + " ");
      }
      System.out.println();
     
      // Modify objects being iterated
      ListIterator<String> litr = al.listIterator();
      while(litr.hasNext()) {
         String element = litr.next();
         litr.set(element + "+");
      }
      System.out.print("Modified contents of al: ");
      itr = al.iterator();
      while(itr.hasNext()) {
         String element = itr.next();
         System.out.print(element + " ");
      }
      System.out.println();

      // Now, display the list backwards
      System.out.print("Modified list backwards: ");
      while(litr.hasPrevious()) {
         String element = litr.previous();
         System.out.print(element + " ");
       }
       System.out.println();
    }
}


Низове

В Java обработката на низове се извършва чрез един специфичен клас с име "String". Дори и литералите (константите) низове се третират като обекти от този клас.

Низовете от символи са непроменяеми. Един път създаден обект от тип низ не може да променя стойността си. Операциите, които позволяват да се замени някакъв символ или размерът на даден низ имат като резултат създаването на нов низ.

        String string = "example: making string";
        int lenght = string.length();
        String concatenation = "Pierre" + " and Marie";

Обект от тип String може да се конструира от масив от от символи или от масив от десетични, осмични или шестандесетични числа:
class Test{
    public static void main(String[] a){
        char datac[ ] = {'p', 'a', 'r', 'c'};
        String sc = new String(datac);
        char datad [ ] = {65,66,67};
        String sd = new String(datad, 0,3);
        char datao [ ] = {065,066,067};
        String so = new String(datao, 0,3);
        char datah [ ] = {0x65,0x66,0x67};
        String sh = new String(datah, 0,3);
        System.out.println(" c:"+sc+ "\n 8:"+so+"\n 10:"+sd+"\n 16:"+sh);
    }
}
c:parc
8:567
10:ABC
16:efg

Преобразуване към низ

Статичният метод String.valueOf() позволява преобразуването на различни типове под формата на ни от символи:

        int i;  //...   
       String number = String.valueOf(i);

Всички обекти в Java притежават един метод toString() наследен от класа Objet, който метод се използва от String.valueOf() за представяне под формата на низ.   

       String number1 = "" + i;

Преобразуване от низ

За това преобразуване се използват методите valueOf(), които се осигуряват от класовете обвивки(wrapper):

        int i = Integer.valueOf("126").intValue();            //основа = 10
        float f = Float.valueOf("14.75").floatValue();       //основа = 10
        int k = Integer.parseInt("234");                            //основа = 10
        int j = Integer.parseInt("ef",racine);
        long l = Long.parseLong("abcd",racine);

racine  - lосновата на бройната система, която може да бъде между Character.MIN_RADIX и Character.MAX_RADIX (2 и 32).

Примери:

 parseInt("0", 10)                        -> 0
 parseInt("473", 10)                    -> 473
 parseInt("-0", 10)                       -> 0
 parseInt("-FF", 16)                    -> -255
 parseInt("1100110", 2)             -> 102
 parseInt("2147483647", 10)    -> 2147483647
 parseInt("-2147483648", 10)    -> -2147483648
 parseInt("2147483648", 10)    генерира NumberFormatException
 parseInt("99", 8)                       
генерира  NumberFormatException
 parseInt("Kona", 10)                
генерира NumberFormatException
 parseInt("Kona", 27)                -> 411787

Сравнения

Релационните оператори сравняват само псевдонимите.

méthode equals(), equalsIgnoreCase(), compareTo().

        String one = "something";
        String two = "something";
        String three = "SOMETHING";
        if (one == two)         //невярно
        if(one.equals(two))     //вярно 
        
if(one.equals(three))     //невярно 
        if (one.equalsIgnoreCase(three))     //вярно
        if(one.compareTo(three) > 0)     //вярно
        if(one.compareTo(two) ==0)     //вярно

Пример:
 
public class StringEx{
   public static void main(String a[]){
         String names [ ] = {"Rose","Anabelle", "Gerard", "Francoise", "Erik","Constance"},name;
         for(boolean ok = false; !ok; ){
              ok=true;
              for(int i = 0; i < names.length-1; i++){
                    if(names[i].compareTo(names[i+1])>0){
                        name = names[i];
                        names[i] = names[i+1];
                        names[i+1] = name;
                        ok = false;
                    }
              }
         }
         for(int i = 0; i <names.length;i++)
            System.out.println (names[i] + " : "+names[i].length()+" lettres");
    }
}
Anabelle : 8 lettres
Constance : 9 lettres
Erik : 4 lettres
Francoise : 9 lettres
Gerard : 6 lettres
Rose : 4 lettres

Някои полезни методи: 

public char charAt(int index)
public boolean endsWith(String suffix)
public int indexOf(String str)
public int indexOf(String str,int fromIndex)
public int lastIndexOf(String str)
public String replace(char oldChar,char newChar)
public boolean startsWith(String prefix)
public String substring(int beginIndex)
public String substring(int beginIndex,int endIndex)
public String toUpperCase()
public String toLowerCase()
public String trim()


Клас StringTokenizer

Разделител - space, табулация

import java.util.StringTokenizer;
public class Test{
public static void main(String arg[]){
String s = "Java is a general-purpose, class-based, and object-oriented language";
StringTokenizer st = new StringTokenizer(s);
while(st.hasMoreTokens()){
String word = st.nextToken();
System.out.println(word);
}
}
}

Разделител символите '/', ':' и '.'

import java.util.StringTokenizer;
public class Test{
public static void main(String arg[]){
String s1 = "http://www.javasoft.com";
StringTokenizer st1 = new StringTokenizer(s1,"/:.");
while(st1.hasMoreTokens()){
String word = st1.nextToken();
System.out.println(word);
}
}
}

Клас StringBuffer

Обектите са променяеми.
Класът StringBuffer има класическата функционалност, но няма никаква връка с класа String и методите му често имат различни имена.

• промяна на символ на дадена позиция: setCharAt();
• достъп до символ : charAt();
• добавяне на низ в края : append() приема аргументи от примитивните типове и от тип String;
• вмъкване на низ на определена позиция : insert(),
• заместване на част от низ : replace(),
• преобразуване на StringBuffer към String : toString().
• ensureCapacity()


public class Test{
public static void main(String arg[]){
StringBuffer sBuf = new StringBuffer ("new ") ;
sBuf.append("test string buffer");
System.out.println (sBuf) ;
sBuf.setCharAt (3, 'J'); System.out.println (sBuf) ;
sBuf.append (" 2") ; System.out.println (sBuf) ;
sBuf.insert (3, "langage ") ; System.out.println (sBuf) ;
}
}