Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Маленький тест


Автор: Domestic Cat 21.6.2004, 17:06
Думаю что многие знают, но все же smile.gif

Есть такая программа:
Код

public class Test
{
   public static void main(String [] args)
   {
       for (int i = 0; i < args.length; i++)
       {
           System.out.println(args[i]);
       }
   }
}


Вопрос: что она выдаст если ее запустить:

java Test *

smile.gif

Автор: Sun 21.6.2004, 17:53
Список файлов в текущей директории?

Автор: AntonSaburov 21.6.2004, 17:55
Век живи, век учись - дураком помрешь. Я не знал. Класс.

Автор: Domestic Cat 21.6.2004, 18:03
smile.gif smile.gif
Под UNIXом можно попробовать еше

java Test .*

и получить список hidden фаuлов.


Автор: Nobody 21.6.2004, 18:07
Ну вполне логично вообще-то. Шелл заменяет * на список файлов.

Автор: Sun 21.6.2004, 18:26
Мне еще нравиться загадка как изменить этот класс, не делая никаких изменений в методе main, чтобы он вывел например строку "Hello, world!".

Автор: Domestic Cat 21.6.2004, 19:30
java Test "Hello, World!" ?

smile


Автор: DarkDS 21.6.2004, 21:06
Цитата(Domestic @ 21.6.2004, 17:06)

Вопрос: что она выдаст если ее запустить:

java Test *

smile.gif

Для виндозы то же что и при
Код
java Test *.*

А
Код
Test *.java > test
вообще ничего не выдаст... только почему то создаст файл тест biggrin.gif с одержимым Test.java biggrin.gif

Автор: Domestic Cat 21.6.2004, 21:17
Кстати, создав фаил
Код

// file f
-deprecation
mysuperlongnamedpackage.anotherpackage.ClassNumberOne
mysuperlongnamedpackage.anotherpackage2.ClassNumberTwo

классы можно компилить так:

javac @f

smile.gif


Автор: Sun 22.6.2004, 11:02
Цитата(Domestic @ 21.6.2004, 16:30)
java Test "Hello, World!" ?

smile.gif

Нет, я имел в виду как поменять скажем такой класс
Код

public class Test
{
  public static void main(String [] args)
  {
       System.out.println("Some text");
  }
}

не меняя текст метода main вывести первой строкой "Hello, World!"

Автор: Domestic Cat 22.6.2004, 15:25
Ну так ето еше проше :
Код

public class Test
{

  static
  {
         System.out.println("Hello, World!");
  }

  public static void main(String [] args)
  {
       System.out.println("Some text");
  }

}


- поскольку static блоки и переменные всегда инициализируются первыми

Автор: Domestic Cat 22.6.2004, 15:39
Кстати тогда другои вопрос - как, не меняя метода main сделать так чтобы программа напечатала только "Hello, World" ?

Ну и заодно - как, не меняя метода main сделать так, чтобы программа
Код

public class Test
{
   public static void main(String [] args)
   {
       while (true);
   }
}


печатала "Hello World" при одновременном нажатии 2х клавиш?

Автор: AntonSaburov 22.6.2004, 15:57
Т.е. уже издеваемся smile.gif

Код

public class Test
{
  static
  {
     System.out.println("Hello, world!");
     System.exit(0);
  }
  public static void main(String [] args)
  {
      while (true);
  }
}

Автор: Domestic Cat 22.6.2004, 16:03
Ага - ето про первыu вопрос smile.gif А про 2 клавиши ? Печатать она должна именно ПРИ нажатии.

biggrin.gif

PS. Можно добавить один класс, но GUI и KeyListener использовать нельзя

Автор: ElectricalStorm 22.6.2004, 19:20
Domestic Cat класс
побольше бы таких приколов...



Автор: Domestic Cat 22.6.2004, 19:41
biggrin.gif biggrin.gif biggrin.gif

сформулирую вопрос еше раз:

что нужно добавить к классу
Код

public class Test
{
   public static void main(String [] args)
   {
       while (true);
   }
}

чтобы при одновременном нажатии 2х клавиш программа напечатала "Hello World"

1. Изменять main нельзя
2. Пользоваться GUI / Listenerami и Stream'ами (кроме System.out.println) нельзя.
3. Можно добавить 1 класс

smile.gif

Автор: ElectricalStorm 22.6.2004, 19:58
Можно сделать класс потомок от Thread и в статике как показанно выше запустить поток...
если так нельзя то я предпологаю что эти магитческие две кнопки Ctrl + D или Z или С
тоесть например ситается ввод все в том же статике через System.in а по завершению ввода печатаем Hello и выходим

наверно что типа такого ... smile.gif


Автор: LSD 22.6.2004, 19:59
Код

public class Test
{
 static
 {
   Runtime.getRuntime().addShutdownHook(new Thread(new MyHook()));
 }
 
 public static void main(String[] args)
 {
   while (true);
 }
 
 private static class MyHook implements Runnable
 {
   public void run()
   {
     System.out.println("Hello World!");
   }
 }
}

Отзывается на Ctrl+Break biggrin.gif biggrin.gif biggrin.gif

Автор: Domestic Cat 22.6.2004, 20:08
Браво LSD adv/super.gif thumbs-up.gif

Было бы у меня 100 постов добавил бы репутацию smile.gif smile.gif biggrin.gif

Автор: LSD 22.6.2004, 20:41
Переживу smile.gif , а еще вопросы есть? Мне понравилость!
А вот мой: можно ли запретить наследование не объявляя класс final?

Автор: DarkDS 22.6.2004, 20:56
Цитата(LSD @ 22.6.2004, 20:41)
Переживу smile.gif , а еще вопросы есть? Мне понравилость!
А вот мой: можно ли запретить наследование не объявляя класс final?

Объявить все конструкторы приватными smile.gif

Автор: Domestic Cat 22.6.2004, 20:59
Код

class CannotBeInheritedFrom
{
   public CannotBeInheritedFrom() throws Exception
   {
       throw new Exception("You cannot inherit from this class");
   }
   private CannotBeInheritedFrom(int i)
   {
   
   }
   static final CannotBeInheritedFrom getInstance()
   {
       CannotBeInheritedFrom instance = new CannotBeInheritedFrom(1);
       return instance;
   }
}

Автор: DarkDS 22.6.2004, 21:01
Цитата(Domestic @ 22.6.2004, 20:59)
Код

class CannotBeInheritedFrom
{
   public CannotBeInheritedFrom() throws Exception
   {
       throw new Exception("You cannot inherit from this class");
   }
   private CannotBeInheritedFrom(int i)
   {
   
   }
   static final CannotBeInheritedFrom getInstance()
   {
       CannotBeInheritedFrom instance = new CannotBeInheritedFrom(1);
       return instance;
   }
}

так все равно проще:
Код

class CannotBeInheritedFrom
{
   private CannotBeInheritedFrom(){}

   static final CannotBeInheritedFrom getInstance()
   {
       CannotBeInheritedFrom instance = new CannotBeInheritedFrom();
       return instance;
   }
}

Автор: Domestic Cat 22.6.2004, 21:07
Согласен smile.gif Запостил первое что на ум пришло.

Автор: Domestic Cat 22.6.2004, 21:40
Ок, вопрос такоу:
Сколько памяти на хипе заuмет Object (то есть полученныж как Object object = new Object()) . Сколко памяти нужно на об#ект если он содержит поле типа byte (boolean, int, long, double, float)?
smile.gif

PS, Naprimer
Код

public class MyObject
{
      public int variable; // byte / boolean/ long / double / float
}

Автор: AntonSaburov 23.6.2004, 17:13
Я тут тестик навалял - у меня такие вот числа получились:
Просто Object жрет аж 200 байтов. Хотя я не понял -почему. Надо покопатьс в документации. Или может кто подскажет.

А любое поле (byte, float, double ...) добавляет еще 8 байт.

Автор: Domestic Cat 23.6.2004, 17:40
По идее Object ест только 8 баuт плюс 8 баuт на лyбое поле, хотя если примитив меньше 8 баuт то JVM впихивает 2 примитивa в те же 8 баuт.

smile.gif

Код

class MemoryTest
{    
   public long calculateMemoryUsage(ObjectFactory factory)
   {      
       Object handle = factory.makeObject();      
       long mem0 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();      
       long mem1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
       handle = null;  
       System.gc(); System.gc(); System.gc(); System.gc();      
       System.gc(); System.gc(); System.gc(); System.gc();      
       System.gc(); System.gc(); System.gc(); System.gc();      
       System.gc(); System.gc(); System.gc(); System.gc();      
       
       mem0 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
       handle = factory.makeObject();
   
       mem1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();      
       return mem1 - mem0;    
   }    
   
   public void showMemoryUsage(ObjectFactory factory)
   {
           long mem = calculateMemoryUsage(factory);      
           System.out.println( factory.getClass().getName() + " produced "        
                 + factory.makeObject().getClass().getName() +
                 " which took " + mem + " bytes");    
   }
}

interface ObjectFactory
{    
       public Object makeObject();  
}

public class Test
{
   public static void main(String [] args)
   {
       MemoryTest mt = new MemoryTest();
       mt.showMemoryUsage(new MyFactory());
   }
}


nu a MyFactory menjaem kak hotim:

Код

class MyFactory implements ObjectFactory
{    
        private static class MyObject
        {      
                boolean b;    
        }    

       public Object makeObject()
      {      
             return new MyObject();    
      }  
}

Автор: LSD 23.6.2004, 19:02
Цитата(Domestic @ 22.6.2004, 21:40)
Ок, вопрос такоу:
Сколько памяти на хипе заuмет Object (то есть полученныж как Object object = new Object()) . Сколко памяти нужно на об#ект если он содержит поле типа byte (boolean, int, long, double, float)?

1) Это по моему зависит от реализации JVM
2) А как вы выяснили?
3) Domestic Cat у вас случайно не Power Mac G5?

От класса с приватными конструкторами может наследовать внутренний класс. И если он public то от него можно вполне успешно наследовать дальше smile.gif . А как от него наследовать если он не static?

Автор: Domestic Cat 23.6.2004, 21:53
1. Зависит, но вроде на многих дает 8 баит на примитив. Интересно сравнить с M$JVM
2. Выяснили что ? smile.gif
3. 700 MHz PowerPC G4 / 384 MB SDRAM

А вопрос хоpоshии wink.gif с первого захода не взjaл ...

Автор: LSD 23.6.2004, 22:12
Цитата
Выяснили что ?

Как выяснили сколько байт идет на примитив, и на пустой объект.

Цитата
700 MHz PowerPC G4 / 384 MB SDRAM

А я надеялся что 64 битная машинка, можно было-бы сравнить разные JDK.

Запретить наследование от класса можно приватными конструкторами, throw Exception, System.exit() и т.д. не запрещает наследовать, но не дает создавать экземпляры объекта при помощи конструктора. При большом желании это можно обойти сериализацией.
Но если все-таки есть внутренний класс, и если он public то от него можно вполне успешно наследовать дальше. А как от него наследовать если он не static?

Автор: Domestic Cat 23.6.2004, 23:04
Цитата
Как выяснили сколько байт идет на примитив, и на пустой объект.


В пред-предыдушем посте программа, она сравнивает размер хипа до и после new MyObject.

От внутреннего класса можно наследоват так:
Код

class Outer
{
     private Outer () {}
    class Inner
    {}

     static class StaticInner extends Outer {}
}

class Outer2 extends Outer.StaticInner
{
     class Inner2 extends Inner
     {}
}


Но вот если нет inner static класса ... dontgetit.gif точнее так : если нет static класса а Inner наследует от Outer ..

Kласс! smile.gif Мне нравится

Автор: Domestic Cat 24.6.2004, 17:06
biggrin.gif biggrin.gif biggrin.gif

Dodumalsja, odnako smile.gif
Код

class Outer
{
   private Outer () {}
   
   class Inner extends Outer
   {}
}

class Outer2 extends Outer.Inner
{  
   Outer2(Outer outer)
   {
       outer.super();
   }
}


Добавлено @ 17:15
Мои вопрос: // простоu smile.gif

есть программа:
Код

class MyFrame extends JFrame
{
    MyFrame()
    {
        init();
        setSize(300, 300);
        setVisible(true);
    }

    private void init()
   {
        JButton button = new JButton("I am a button");
        JPanel panel = new JPanel();
        panel.add(button);
        getContentPane().add(panel);
   }
}


Kak изменить цвет подписи на кнопке если
1. добавлять вызов каких-либо методов в методы класса MyFrame нельзя
2. button - инстанс JButton, добавлять своu класс наследуюшиu от JButton нельзя

Автор: LSD 24.6.2004, 18:42
Код

public static void findThatDamnButton(Component c)
{
 if(c instanceof JButton && ( (JButton)c).getText().equals("I am a button"))
   ( (JButton)c).setForeground(Color.RED);
 if(c instanceof Container)
 {
   Component[] childrens = ( (Container)c).getComponents();
   if(childrens != null)
     for(int i = 0; i < childrens.length; i++)
       findThatDamnButton(childrens[i]);
 }
}

И вызываем findThatDamnButton() для экземпляра MyFrame smile.gif

Автор: Domestic Cat 24.6.2004, 18:57
Хорошо smile.gif А если нужно чтобы при запуске text кнопкu уже был красного цвета? то есть как исправить код с теми же условиями что и раньше? biggrin.gif

Автор: LSD 24.6.2004, 19:11
А методы добавлять в MyFrame можно или его вообще изменять нельзя?

Автор: Domestic Cat 24.6.2004, 19:17
Да, надо было мне лучshе правила продумать smile.gif
Даваuте так:
Nel'zja дописывать novye классы (inner, nested, top-level), novye методы (main, ...) и novye вызовы методов в init i constructor.

Автор: LSD 24.6.2004, 19:34
Код
UIManager.put("Button.foreground" , Color.RED);

Автор: Domestic Cat 24.6.2004, 19:41


Код

class MyFrame extends JFrame
{
    MyFrame()
    {
        init();
        setSize(300, 300);
        setVisible(true);
    }

    private void init()
   {
        JButton button = new JButton("I am a button");
        JPanel panel = new JPanel();
        panel.add(button);
        getContentPane().add(panel);
   }
  public static void main(String args [])  // dopisal metod, tak chto eta programma zapuskaetsja
                                                            // iz comandnoj stroki
 {
       new MyFrame();
 }
}


Nel'zja дописывать novye классы (inner, nested, top-level), novye методы и novye вызовы методов в init, main i constructor.

UIManager.put("Button.foreground" , Color.RED); - eto vyzov medoda biggrin.gif


Автор: LSD 24.6.2004, 19:48
Исходный код вообще main() не содержит значит его и запустить можно только из вне. Я так и предпологал делать.
Переформулирую вопрос а что вообще можно делать с MyFrame? Методы переписывать можно? Если его никак не менять и запусткать его а не свой класс, то один выход мучить JDK smile.gif smile.gif smile.gif (менять UI defaults, ставить свой Look&Feel и т.д.)

Автор: Domestic Cat 24.6.2004, 20:01
Можно менять аргументы передаваемые методам smile.gif

Автор: LSD 26.6.2004, 12:23
Цитата(Domestic @ 24.6.2004, 20:01)
Можно менять аргументы передаваемые методам smile.gif

Единственный метод аргументы которого мы можем поменять это main(), но он их не использует никак, так что единственный вариант это мучить JVM, пытаясь вызвать загрузку свих классов, до MyFrame.

Автор: Domestic Cat 26.6.2004, 19:48
biggrin.gif ответ такоu:

Код

...
JButton button = new JButton("<html><font color=red>I am a button</font></html>");
...


biggrin.gif biggrin.gif biggrin.gif

Автор: AntonSaburov 28.6.2004, 11:22
Цитата
JButton button = new JButton("<html><font color=red>I am a button</font></html>");

Мда-а-а. А ведь встречал я такой вариант.

Автор: Domestic Cat 29.6.2004, 21:33
Ну это совсем просто (biggrin.gif)
что выдаст такая программа (отвечать быстро, не задумываясь)

Код


class Test
{
     public static void main(String[] args)
     {
           int i = 10;
           i = i++;
           System.out.println(" Value of i is " + i);
     }
}

Автор: LSD 29.6.2004, 21:49
Вот это что мне не нравиться в Java, все эти сишные штучки пред и пост инкременты, только запутывают код. Должна быть 10.

Автор: Domestic Cat 30.6.2004, 01:36
smile.gif

Что ж, еше вопрос.

Предположим, что на момент запуска данноu программы у нас 12 января 2004 года
и ровно 15 часов 10 минут. Программа исполняется в течение 1 миллисекунды
(это всего лишь предположение smile.gif ).

Вопрос: Какого цвета будет панель если для заливки использовать color?

Код


import java.util.*;
import java.awt.*;

class Test
{

    public static void main(String[] args)
   {
        Random r = new Random();
        Color color = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
   }
}

Автор: AntonSaburov 30.6.2004, 11:57
Набросал такой вот тест - хотя по идее можно было бы подсчитать. В JavaAPI вся необходимая информаци есть. Но может я не совсем прав и есть какой-то трюк ?

Код

import java.util.*;
import java.awt.*;

class Test
{

  public static void main(String[] args)
  {
       GregorianCalendar gc = new GregorianCalendar(2004, 1, 12, 15, 10);
       Random r = new Random(gc.getTimeInMillis());
       Color color = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
       System.out.println(color);
  }
}

Автор: Domestic Cat 30.6.2004, 15:21
Согласен smile.gif

только
1. Январь - это не 1 а 0
2. gc.getTimeInMillis() будет давать каждыu раз разные значения, нужно обнулять последние цифры

biggrin.gif

Автор: AntonSaburov 30.6.2004, 16:09
Цитата
1. Январь - это не 1 а 0

Да, тут ошибочка вышла smile.gif

Цитата
2. gc.getTimeInMillis() будет давать каждыu раз разные значения, нужно обнулять последние цифры

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

Автор: Domestic Cat 30.6.2004, 16:15
Да, у меня тоже ошибочка - GregorianCalendar деuствительно устанавливает секунды/миллисекунды на 0.
Я писал
Код

Calendar cal = Calendar.getInstance();
cal.set(2004, 0, 12, 15, 10, 0);

- тогда их нужно самому занулять smile.gif

Автор: AntonSaburov 30.6.2004, 16:42
Кстати тема хорошая получилась - можно попробовать ее причесать и выкатить что-то вроде Tips&Tricks. И вести ее постоянно.

Автор: Sun 30.6.2004, 17:30
Цитата(AntonSaburov @ 30.6.2004, 13:42)
Кстати тема хорошая получилась - можно попробовать ее причесать и выкатить что-то вроде Tips&Tricks. И вести ее постоянно.

Хорошая идея. Мне эта тема тоже очень нравиться.

Автор: Domestic Cat 30.6.2004, 18:11
Цитата
Кстати тема хорошая получилась - можно попробовать ее причесать и выкатить что-то вроде Tips&Tricks. И вести ее постоянно.


Неплохо было бы smile.gif.

Автор: Domestic Cat 1.7.2004, 16:05
Продолжим.

Есть такая программа:
Код

import java.awt.*;
import javax.swing.*;

public class Test extends JFrame
{
   Test()
   {
       super("Miracle");
       JPanel panel = new JPanel();
       JTextField tf = new JTextField(15);
       panel.add(tf);
       getContentPane().add(panel);
       setSize(400, 100);
       tf.requestFocus();
       setLocationRelativeTo(null);
       setDefaultCloseOperation(EXIT_ON_CLOSE);
       setVisible(true);
   }
   public static void main(String[] args)
   {
       Test test = new Test();
   }
}


Nuzhno, чтобы в текстовом поле при нажатии любоu клавиши отображался ее код.
Пользоваться любыми Listener'ами нельзя. Других ограничении нет.

Автор: LSD 1.7.2004, 21:51
Код

public class MyTextField extends JTextField
{
 public MyTextField(int columns)
 {
   super(columns);
 }
   
 protected void processKeyEvent(KeyEvent e)
 {
   super.processKeyEvent(e);
   setText(Integer.toString(e.getKeyCode()));
 }
}

Автор: Domestic Cat 1.7.2004, 22:07
biggrin.gif biggrin.gif

Автор: Domestic Cat 1.7.2004, 23:39

Предположим, вы запустили многопотоковую программу и вам кажется что она зависла.
Как определить, находится ли она в состоянии дедлока в данныu момент?

Автор: Sun 2.7.2004, 10:55
killall -3 java?

Автор: Domestic Cat 2.7.2004, 20:37
По-моему, Ctrl + \ или Ctrl + break smile.gif

Автор: Sun 2.7.2004, 20:53
Цитата(Domestic @ 2.7.2004, 17:37)
По-моему, Ctrl + \ или Ctrl + break smile.gif

Да, но когда Java запущена как демон (например Tomcat), то такой вариант больше подходит smile.gif

Автор: LSD 2.7.2004, 23:45
Это зависит от JVM, например Microsoft JVM такого не делает, если JVM запущенна без консольного окна (под виндами это javaw) то это тоже не сработает.
У меня другой вопрос, как получить (програмно) все потоки которые в данный момент активны?

Автор: Domestic Cat 2.7.2004, 23:56
Код

public class Test
{
   public static void main(String [] args)
   {
       ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();
       while (root.getParent() != null)
       {
           root = root.getParent();
       }
       visit(root, 0);
   }
   public static void visit(ThreadGroup group, int level)
   {
       int numThreads = group.activeCount();
       Thread[] threads = new Thread[numThreads * 2];
       numThreads = group.enumerate(threads, false);
       for (int i = 0; i < numThreads; i++)
       {
           Thread thread = threads[i];
           System.out.println(thread.getName());
       }
       int numGroups = group.activeGroupCount();
       ThreadGroup[] groups = new ThreadGroup[numGroups * 2];
       numGroups = group.enumerate(groups, false);
       for (int i = 0; i < numGroups; i++) {
           visit(groups[i], level + 1);
       }
   }
}

Автор: Domestic Cat 3.7.2004, 00:47
Слова "кафе" и "бэби" - кому-нибудь о чем-нибудь говорят? smile.gif

// Хотя я знаю кто ответит первым biggrin.gif

Автор: LSD 3.7.2004, 01:00
CA FE BA BE заголовок класс файла biggrin.gif biggrin.gif biggrin.gif
Давай детка выпьем кружечку кофе (того самого) biggrin.gif biggrin.gif biggrin.gif
Добавлено @ 01:03
Кстати а где оставил о себе память Марк Збыковский? /** @hint к Java не относится */

Автор: Domestic Cat 3.7.2004, 01:23
biggrin.gif DOS executable magic number - MZ biggrin.gif biggrin.gif biggrin.gif

Автор: Domestic Cat 3.7.2004, 01:43
Пусть у меня есть программа и я не хочу, чтобы юзер мог запустить 2 или больше
копиu данноu программы на одноu и тоu же машине. Нужно...

Автор: Domestic Cat 5.7.2004, 16:42
Один из вариантов: открывать сокет на определенном порту, в случае поимки BindException делать
System.exit(1).

Есть программа:
Код

public class t
{
   public static int NUMBER = 1000;
   public static void main(String args[])
   {
       long sum = 0;
       int count = 0;
       long last = System.currentTimeMillis();
       while(count < NUMBER)
       {
           long current = System.currentTimeMillis();
           if (current > last)
           {
               long result = current - last;
               sum += result;
               count++;
               last = current;
           }
       }
       System.out.println((float) sum / count);
   }
}

Pochemu она бyдет выдавать разные значения на разных ОС?

Автор: ElectricalStorm 5.7.2004, 18:01
CA FE BA BE заголовок класс файла - КЛАСС

Автор: LSD 5.7.2004, 18:57
Цитата
Пусть у меня есть программа и я не хочу, чтобы юзер мог запустить 2 или большекопиu данноu программы на одноu и тоu же машине.

Ну еще есть вариант с файлами, но для апплета они не подходят оба sad.gif .
Цитата
Pochemu она бyдет выдавать разные значения на разных ОС?

А почему она должна выдавать одинаковые результаты? Результаты вариируются от запуска к запуску, не говоря уж о использовании разных режимов выполнения (-client, -server, -Xint).

Автор: Domestic Cat 5.7.2004, 19:06
Хм, pечь идет о совсем разных результатах smile.gif Zапускается она
java -Test
значения отличаюшиеся на, скажем, <= 5f cчитать одинаковыми.
Добавлено @ 19:09
Хинт: на Маке она выдаст что-то около 1, а вот на 95, 98, XP biggrin.gif?

Автор: LSD 5.7.2004, 19:13
Ну под W2K + Sun JDK, System.currentTimeMillis() выдает результат с точность 10мсек, а под другими системами и другими JDK ситуация может быть иная.

Автор: Domestic Cat 5.7.2004, 19:20
Ага, только проблема не у System.currentTimeMillis(), а у таuмера ОС. Точность таuмеров такая:

Windows 95/98/Me: 55 ms
Windows NT/2000/XP : 10-15 ms
Mac / Linux : 1 ms

Tak что если я вывожу 50 фреuмов / сек и обновляю экран каждые 20 мс, то на
98 виндах каждыu второu фреuм выпадет sad.gif

Автор: LSD 5.7.2004, 19:34
Если обновлять по таймеру может быть, а если в цикле, то все зависит от скорости системы.

Автор: Domestic Cat 5.7.2004, 19:39
Обычно обновляется по таuмеру, в играх например. Иначе картинка будет дергаться поскольку
нагрузка процессора в разные моменты времени будет разноu.
Добавлено @ 19:41
Хотя в утилитах Java3D / Windows есть более точныu таuмер.

Автор: redrick 6.7.2004, 01:29
а эти времена определяются только реализацией JDK или это принципиальные ограничения осей(хотя с чего бы) ?

Автор: Domestic Cat 6.7.2004, 02:05
"... точность зависит от оперционноu сuстемы. Например, многие ОС измеряjут время в
десятках миллисекунд".

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#currentTimeMillis()

Автор: redrick 6.7.2004, 02:09
понятно, спасибо

Автор: Domestic Cat 6.7.2004, 15:42
Программа:
Код

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame implements ActionListener
{

   private JTextArea text;
   private JButton run;

   public Test()
   {
         
       text = new JTextArea(50, 50);

       run = new JButton("Compile and run");
       run.addActionListener(this);
       Container cp = getContentPane();
       cp.add(text, BorderLayout.CENTER);
       JPanel panel = new JPanel();
       panel.add(run);
       cp.add(panel, BorderLayout.SOUTH);
       setSize(300, 300);
       setLocationRelativeTo(null);
       setDefaultCloseOperation(EXIT_ON_CLOSE);
       setVisible(true);
    }
   public static void main(String[] args) {
       new Test();

   }
   public void actionPerformed(ActionEvent ae)
   {}
}


Надо, чтобы юзер мог набрать произвольныu Java-код в JTextArea. При нажатии на кнопку этот код должен быть записан в метод main созданного программоu java-фаила, скомпилирован и выполнен.

PS. Runtime использовать нельзя biggrin.gif

Автор: AntonSaburov 6.7.2004, 16:04
Если ответ в com.sun.tools.javac.Main.compile, то есть еще одно предложение - при запуске программы в CLASSPATH не использовать tools.jar smile.gif
Т.е. запуск программы должен быть просто
java Test

P.S. Само собой, что и в системной переменной CLASSPATH этой библиотеки быть не должно.

Автор: Domestic Cat 6.7.2004, 16:27
Цитата
Если ответ в com.sun.tools.javac.Main.compile,

biggrin.gif
Цитата
при запуске программы в CLASSPATH не использовать tools.jar
Т.е. запуск программы должен быть просто
java Test
P.S. Само собой, что и в системной переменной CLASSPATH этой библиотеки быть не должно.

adv/eek.gif
А я так и запускаю, кроме того у меня -то и tools.jar нет, и CLASSPATH не выставлен (bad baad Apple biggrin.gif)

Автор: AntonSaburov 6.7.2004, 16:36
Но ведь где-то у тебя должен быть com.sun.tools.javac.Main ?

Автор: Domestic Cat 6.7.2004, 16:42
Он сидит в classes.jar, вместе с java, javax, sunw, org и sun.

Автор: AntonSaburov 6.7.2004, 16:49
Цитата
Он сидит в classes.jar, вместе с java, javax, sunw, org и sun.

Понятно. Под Винду в версии 1.4 он находится в отдельном JAR-файле tools.jar.
Ладно, тогда обобщим вопрос smile.gif

Как можно использовать классы из JAR-файла, не указывая этот файл в опции -classpath ?

Автор: Domestic Cat 6.7.2004, 17:01
Поместить его в ext директорию, которую можно наuти так:

Код

System.getProperty( "java.ext.dirs" );


smile.gif

Автор: LSD 6.7.2004, 19:57
Цитата
Как можно использовать классы из JAR-файла, не указывая этот файл в опции -classpath ?

Можно реализовать свой ClassLoader.
Вот мне не понятен другой вопрос: если во время работы программы изменить classpath (System.setProperty()), то никакого влияния на SystemClassLoader это не оказывает, может есть еще варианты?

Автор: Domestic Cat 6.7.2004, 21:41
Можно запустить
Код

Runtime.getRuntime().exec("java -cp /Users/myName/Programs/ MyClass");

но разницы особож нет smile.gif

Автор: LSD 6.7.2004, 21:59
Не это не вариант. С таким же успехом я могу написать батничек.
Мне надо как-то реализовать, механизм плагинов, вот я и думаю как. Идеально если для пользователя это будет так:
- поместил в нужный каталог jar
- в меню включил появился плагин, ты его если надо выключил
вот пока думаю как бы это реализовать.

Автор: Domestic Cat 6.7.2004, 23:54
Ну вот что-то типа того:
Код

import java.util.*;
import java.net.*;
public class Test
{
   public static final String path = "file:///Users/DomesticCat/MyFiles/";
   public static void main(String[] args)
   {
       String userEntered = "jode.swingui.Main";
       StringTokenizer stk = new StringTokenizer(userEntered, ".");
       try
       {
           URL[] url = new URL[] {new URL (path + stk.nextToken() + ".jar")};
           URLClassLoader loader = new URLClassLoader(url);
           System.out.println(loader.loadClass(userEntered));
       }
       catch (Exception e)
       {
           e.printStackTrace();
       }
   }
}

Автор: DarkDS 7.7.2004, 13:19
Цитата(LSD @ 6.7.2004, 21:59)
Не это не вариант. С таким же успехом я могу написать батничек.
Мне надо как-то реализовать, механизм плагинов, вот я и думаю как. Идеально если для пользователя это будет так:
- поместил в нужный каталог jar
- в меню включил появился плагин, ты его если надо выключил
вот пока думаю как бы это реализовать.

Оффтоп.
Подобная тема уже поднималась. Я как то объяснял уже один из вариантов smile.gif
http://forum.vingrad.ru/index.php?showtopic=11906&st=0&#entry76499

Автор: Domestic Cat 7.7.2004, 15:23
Цитата
Оффтоп.
Подобная тема уже поднималась. Я как то объяснял уже один из вариантов


Я чего-то не понял. Там же о создании обэцктов при заранее неизвестном названии класса ?

Автор: Domestic Cat 7.7.2004, 15:50
Данную программу можно "ускорить" на 30%(на Маке; на Wиндах может быт меньше). Как?:
Код

public class Test
{
   public static void main(String[] args)
   {
       double y = 10.456;
       double w = 0.45;
       double result = 0;
       for (int j = 0; j < 10000000; j++)
       {
           result = 0;
           for(int i = 1; i < 100; i++)
           {
               result += y + w;
           }
       }
       System.out.println(result);
   }
}

Mozhno добавлять поля, умножение, деление и кастинг.

PS. Vnutri ciklov nichego ne menjat'. Tochnost' derzhat' do 3x znakov posle zapjatoj.

Автор: AntonSaburov 7.7.2004, 16:01
Вот такой вариант у меня получился smile.gif
При этом скорость выросла на вскидку раза в 4-5 под Виндой.

Код

public class Test
{
  public static void main(String[] args)
  {
      int y = 10456;
      int w = 450;
      int result = 0;
      for (int j = 0; j < 10000000; j++)
      {
          result = 0;
          for(int i = 1; i < 100; i++)
          {
              result += y + w;
          }
      }
      System.out.println(((float)result)/1000);
  }
}

Автор: Domestic Cat 7.7.2004, 16:05
biggrin.gif

Более обwиu вариант
Код

class Test
{
   private static final int SCALE = 1 << 16; // int is 32-bit
   
   public static void main(String[] args)
   {
       int y = (int)(10.456 * SCALE);
       int w = (int)(0.45 * SCALE);
       int result = 0;
       for (int j = 0; j < 10000000; j++)
       {
           result = 0;
           for(int i = 1; i < 100; i++)
           {
               result += y + w;
           }
       }
       System.out.println((float)result / SCALE);
   }
}


4-5 raz - WOW

Автор: AntonSaburov 7.7.2004, 16:27
Цитата
4-5 raz - WOW

Через java -Xprof Test получил

1.9 и 11.6 секунд.

Автор: Domestic Cat 7.7.2004, 16:29
java -Xprof Test

Удобная штука - показывает сколько времени потрачено на выполнение,
плюс на каждый метод отдельно (в %)

//

Pochti 10 raz biggrin.gif biggrin.gif biggrin.gif

Автор: DarkDS 7.7.2004, 16:43
Цитата(Domestic @ 7.7.2004, 15:23)
Цитата
Оффтоп.
Подобная тема уже поднималась. Я как то объяснял уже один из вариантов


Я чего-то не понял. Там же о создании обэцктов при заранее неизвестном названии класса ?

Так "механизм плюгинов" как раз такой и есть smile.gif)

Автор: Domestic Cat 7.7.2004, 16:55
ОК smile.gif

1. Kstati: известно что есть две части хипа: "молодоu" хип (young heap) и "старыu" (tenure heap). Как узнать сколько раз в течение времени выполнения был запушен сборшик мусора,
сколько он собрал на каждоu части хипа, и сколько времени он потратил?

2. Сборка мусора в старом хипе длится на 1-2 порядка дольше. Если программа
создаeт много обeктов (3D шутер скажем), то это будет давать лаг.
Как минимизировать сборку мусора на старом хипе?

Автор: LSD 7.7.2004, 19:13
Как создать экземпляр класса в Runtime я представляю, у меня вопрос в том как это класс загрузить если он не был прописан в CLASSPATH и как определить тот ли это класс что я ищу (реализует ли он необходимый интерфейс) не загружая этот класс.
Со воторым вопросом можно разобраться потребовав прописать в mainfest нужный класс. Но вот как сделать так чтобы SystemClassLoader загружал файлы из данного jar? Если использовать вариант Domestic Cat с URLClassLoader, то придется предварительно грузить все классы из jar-а, иначе при запуске плагина он может не обнаружить некоторых классов. Это не желательно по тому что плагин может и не использоваться, кроме как получить его имя и показать новый пункт меню, и тогда все эти классы не нужны.

У меня вопрос такой Domestic Cat написал программу которая показывает все Thread-ы, созданные "нормальным" образом, а как ее можно обмануть? Т.е. запустить в той же JVM Thread так чтобы она его не увидела?

Автор: Domestic Cat 7.7.2004, 19:59
LSD, может тебе в сторону Avalon посмотреть (http://avalon.apache.org/) ? Я не работал с ним, но говорят что-то подобное
делает:
Цитата
To use it, you place your common jar files into a directory that functions as the repository. You then create these property files that end with .meta and place them into the repository. You create an instance of the InitialContext class that requires a path to the repository.
You use the context to request "Artifacts" from the repository. The name of the artifact corresponds to a .meta file. It reads the .meta file, creates the classloader and loads the jars listed in the .meta file.

There are code examples that you should be able to follow. However there is one very important item not documented. When you download the repository jars, do not place all of them into the application's class path. Only put the avalon-repository-main in the application's classpath. The other jars go into the repository. The main jar is a boot jar. It loads the others from the repository.

Nu а чтобы обмануть программу, нужно написать сабкласс ThreadGroup и сделать override метода
activeCount()

Код

public class Test
{
   public static void main(String [] args)
   {
       MyGroup trick = new MyGroup();
       Invisible oops = new Invisible(trick);
       Invisible oops1 = new Invisible(trick);
       ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();
       while (root.getParent() != null)
       {
           root = root.getParent();
       }
       visit(root, 0);
   }
   public static void visit(ThreadGroup group, int level)
   {
       int numThreads = group.activeCount();
       Thread[] threads = new Thread[numThreads * 2];
       numThreads = group.enumerate(threads, false);
       for (int i = 0; i < numThreads; i++)
       {
           Thread thread = threads[i];
           System.out.println(thread.getName());
       }
       int numGroups = group.activeGroupCount();
       ThreadGroup[] groups = new ThreadGroup[numGroups * 2];
       numGroups = group.enumerate(groups, false);
       for (int i = 0; i < numGroups; i++)
       {
           visit(groups[i], level + 1);
       }
   }
}

class Invisible extends Thread
{
   Invisible(MyGroup trick)
   {
       super(trick, "");
       start();
   }
   public void run()
   {
       while(true)
       {
             // doing something
       }
   }
}

class MyGroup extends ThreadGroup
{
   public MyGroup()
   {
       super("MyGroup");
   }
   
   public int activeCount()
   {
       return 0;
   }
}

Автор: LSD 7.7.2004, 20:20
Хорошее решение я пошел более радикальным путем, без субклассов.

Автор: Domestic Cat 7.7.2004, 20:29
Цитата
Хорошее решение я пошел более радикальным путем, без субклассов.

А каким, интересно? smile.gif

Автор: DarkDS 7.7.2004, 20:36
Цитата(LSD @ 7.7.2004, 19:13)
Это не желательно по тому что плагин может и не использоваться, кроме как получить его имя и показать новый пункт меню, и тогда все эти классы не нужны.

Эта... Кстати... Создай по этому тему... тама и пообсуждаем smile.gif

Автор: Domestic Cat 7.7.2004, 20:45
Опять флууудим-с ? biggrin.gif
Добавлено @ 20:47
Вопрос про хип не закрыт smile.gif

Автор: LSD 7.7.2004, 21:17
Цитата(Domestic @ 7.7.2004, 20:29)
А каким, интересно?  smile.gif

Я использовал приватный конструктор ThreadGroup. Хотя тут могут быть проблемы с SecurityManager.
Цитата
Эта... Кстати... Создай по этому тему... тама и пообсуждаем

Я пока гляну на Avalon, а там если будут вопросы или не понравиться создам.

Автор: Domestic Cat 8.7.2004, 16:00
1. Чтобы узнать о том, что делал сборщик мусора (=gc), нужно запустить программу с
опцией -verbose:gc
Типичный результат будет таким:
Цитата

[GC 926K->592K(1984K), 0.0133686 secs]
[GC 1103K->692K(1984K), 0.0586286 secs]
[GC 1203K->1000K(1984K), 0.0138741 secs]
[GC 1490K->1412K(1984K), 0.0071983 secs]
[GC 1924K->1837K(2368K), 0.0060598 secs]
[Full GC 1837K->1250K(2368K), 0.3012520 secs]
[GC 1757K->1633K(2664K), 0.0056265 secs]
[GC 2133K->2052K(2664K), 0.0044287 secs]
[GC 2564K->2356K(2920K), 0.0059645 secs]
[Full GC 2356K->2131K(2920K), 0.1983004 secs]
...

(если сборки мусора не было, то ничего он не выдаст конечно)
GC обозначает сборку на молодом хипе, Full GC - на старом; далее идет : [размер хипа до -> размер после (общий размер хипа), вреня потраченное на сборку]
Как видим, сборка на старом хипе заняла в 10 раз больше времени чем на молодом -
правда комп был в плохом настроении, обычно в этом же шутере сборка длится в 10 раз
быстрее на обеих частях хипа.
Более подробную инфу осборке можно получить так: -XX:+PrintGCDetails:

Цитата

[GC [DefNew: 511K->64K(576K), 0.0122158 secs] 926K->592K(1984K), 0.0123501 secs]
[GC [DefNew: 575K->64K(576K), 0.0173724 secs] 1104K->691K(1984K), 0.0174782 secs]
[GC [DefNew: 574K->64K(576K), 0.0141866 secs] 1202K->1009K(1984K), 0.0142940 secs]
[GC [DefNew: 558K->63K(576K), 0.0072319 secs] 1504K->1426K(1984K), 0.0073383 secs]
[GC [DefNew: 575K->64K(576K), 0.0059967 secs][Tenured: 1789K->1262K(1792K), 0.1463170 secs] 1938K->1262K(2368K), 0.1570296 secs]
[GC [DefNew: 506K->64K(576K), 0.0049062 secs] 1768K->1644K(2680K), 0.0050128 secs]


DefNew соответствует молодому хипу, Tenured - старому.
Длительность сборки зависит от размера хипа, поскольку молодой хип меньше, то и убирается он быстрее. Все созданные обьекты попадают сначала на молодой хип; если в течение некоторого времени они все еще нужну, они перемещаются на старый хип.

Автор: ElectricalStorm 8.7.2004, 16:08
Domestic Cat - большое спасибо за информацию !!!
очень интересно

Автор: Domestic Cat 8.7.2004, 16:30
2. Первоначально хип имеет достаточно маленький размер. По мере его заполнения, JVM
пытается высвободить место, убирая мусор. Если это не удается, JVM увеличивает размер хипа.
Если программа создаэт много обэктов в короткий промежуток времени, то JVM много
времени будет уделять перезапускам gc, увеличениям хипа, и т д.
Чтобы минимизировать сборку мусора, нужно изначально создавать достаточно большой хип.
Чтобы узнать необходимый размер, проведем мониторинг памяти:
Код

public class MemMonitor
{
   public static class Data
   {
       float lastValue = 0;
       float min = Float.MAX_VALUE;
       float max = Float.MIN_VALUE;
       float sum = 0;
       int count = 0;

       public void addValue(float value)
      {
           lastValue = value;
           sum+=value;
           count++;
           min = Math.min(min, value);
           max = Math.max(max, value);
       }
       public String toString()
      {
           return "Min: " + toByteFormat(min) + "  " +
                  "Max: " + toByteFormat(max) + "  " +
                  "Avg: " + toByteFormat(sum / count);
       }
   }
   private Data heapSize = new Data();
   private Data allocSize = new Data();
   private Data allocIncPerUpdate = new Data();
   private int numHeapIncs = 0;
   private long startTime = System.currentTimeMillis();

   public void takeSample()
   {
       Runtime runtime = Runtime.getRuntime();
       long currHeapSize = runtime.totalMemory();
       long currAllocSize = currHeapSize - runtime.freeMemory();

       if (currHeapSize > heapSize.lastValue)
      {
           numHeapIncs++;
       }
       if (currAllocSize >= allocSize.lastValue)
       {
           allocIncPerUpdate.addValue(
               (currAllocSize - allocSize.lastValue));
       }
       heapSize.addValue(currHeapSize);
       allocSize.addValue(currAllocSize);
   }

   public static String toByteFormat(float numBytes)
   {
       String[] labels = {" bytes", " KB", " MB", " GB"};
       int labelIndex = 0;
       while (labelIndex < labels.length - 1 && numBytes > 1024)
       {
           numBytes/=1024;
           labelIndex++;
       }
       return (Math.round(numBytes*10)/10f) + labels[labelIndex];
   }

   public String toString()
   {
       long time = System.currentTimeMillis() - startTime;
       float timeSecs = (float)time / 1000;
       return "Total Time: " + timeSecs + "s\n" +
           "Heap: " + heapSize + "\n" +
           "Allocation: " + allocSize + "\n" +
           "Allocation inc/update: " + allocIncPerUpdate + "\n" +
           "Num Heap Incs: " + numHeapIncs;
   }
}

Программа определяет минимальный/максималный размер хипа, выделенной памяти и приращения. Для сбора данных я из цикла вызиваю метод takeSample(); при выходе/заверщении просто передаю обэкт класса MemMonitor в System.out.
При запуске того же шутера я получил:
Цитата

Total Time: 34.754s
Heap: Min: 4.0 MB  Max: 36.9 MB  Avg: 25.1 MB
Allocation: Min: 3.5 MB  Max: 28.9 MB  Avg: 17.9 MB
Allocation inc/update: Min: 1.0 KB  Max: 5.0 MB  Avg: 162.8 KB
Num Heap Incs: 6

(Желательно конечно поработать дольше)
За время выполнения было сделано 29 уборок мусора на молодом хипе, и 11 - на старом, что заняло около 4 секунд!

Видно, что JVM начинает с хипа в 4 мб; он увеличивается до 40 мб. Чтобы посчитать приблизительный размер молодого хипа, учтем ,что приращение за 1 фрейм составляет 162.8 кб; при прорисовке 10 фрэймов/сек за 10 сек мы получим ~ 10 мб идет в молодой хип.

Скажем JVM теперь что изначально нужно 40 мб хипа и 10 мб молодого хипа:

java -Xms40m -Xmn10m -verbose:gc Test

Вот что я получил:
Цитата

[GC [DefNew: 8191K->1024K(9216K), 0.0919743 secs] 8191K->2329K(39936K), 0.0921144 secs]
[GC [DefNew: 9215K->1024K(9216K), 0.0545125 secs] 10521K->9647K(39936K), 0.0546372 secs]
[GC [DefNew: 9216K->1022K(9216K), 0.0940688 secs] 18634K->18593K(39936K), 0.0942104 secs]
[GC [DefNew: 9195K->1023K(9216K), 0.0846478 secs] 29923K->29777K(39936K), 0.0847471 secs]
Total Time: 29.68s
Heap: Min: 39.0 MB  Max: 39.0 MB  Avg: 39.0 MB
Allocation: Min: 2.9 MB  Max: 33.6 MB  Avg: 22.4 MB
Allocation inc/update: Min: 1.0 KB  Max: 7.4 MB  Avg: 207.3 KB
Num Heap Incs: 1


Всего 4 уборки мусора на молодом хипе - и игра идет гораздо плавнее smile.gif

Автор: ElectricalStorm 8.7.2004, 16:40
у меня вот эта команда
java -Xms40m -Xmn4m -verbose:gc Test

ничего не выдает пустую строку sad.gif

Автор: Domestic Cat 8.7.2004, 16:47
Цитата
у меня вот эта команда
java -Xms40m -Xmn4m -verbose:gc Test
ничего не выдает пустую строку


Имеется в виду, что Test- название вашего java-класса; кроме того программа должна создавать
МНОГО обьектов, иначе просто сборшик мусора не запускается - собирать нечего.
Чтобы подключить MemMonitor, нужно из цuкла (например, цuкла анимации) вызывать takeSample().

Добавлено @ 16:53
Попробууте такую программу:
Код

import java.awt.Color;

public class Test
{
   static MemMonitor monitor = new MemMonitor();
   public static void main(String[] args)
   {
       for (int i = 0; i < 1000000; i++)
       {
           monitor.takeSample();
           new Color(100, 100, 100);
       }
       System.out.println(monitor);
   }
}


java -verbose:gc Test

u поекспериментируuте с размерами хипов.

Автор: ElectricalStorm 8.7.2004, 16:59
Спасибо ! все получилось

Автор: ElectricalStorm 8.7.2004, 17:14
А вы не могли рассказать про способы оптимизации Java програм ?
adv/76.gif

Автор: Domestic Cat 8.7.2004, 17:33
smile.gif

Не претендую на абсолютную истину, но попробую.

Не оптимизируйте! Пишите программы, которые понятны, легко дебагить и модифицировать.

На самом деле конечно оптимизировать нужно. Чтобы понять что оптимизировать, помните,
что в основном нагрузка приходится на 10-20% кода. Узнать какой метод наиболее задействован
мозжно, запустив с флагом -Xprof.

На самом деле HotSpot и JIT (Just-In-Time Compiler) делают большую работу по оптимизации. Можно легко найти инфо по этому вопросу. В целом же оптимизация программы программистом сводится к:

1. Использованию оптимальных алгоритмов. Например, для быстрого поиска используйте
HashMap, он быстрее чем, скажем TreeMap.

2. Старайтесь использоват побитовые операции. Вместо х/32 луче использоват х >> 5; вместо
х % 32 - х & 31 (31 = 32 - 1). Работает только для степеней 2.

3. Заменяйте умножение на суммирование, возведение в степень - на умножение.

4. Используйте готовые таблицы значений. Например, если нужно считать синус/косинус и
большая точность вычислений не нужна, используйте готовую таблицу для синуса.

5.Заменяйте операции с float, double на операции с int и делайте кастинг назад в float (тут на предыдущей странице пример есть )

6. Используйте Buffered{}Stream

7. Если нужен рандом -доступ к большим файлам (несколько мб), используйте memory-mapped files (см MappedByteBuffer в Java API). Программа может читать из MappedByteBuffer почти так же быстро, как из памяти.

Автор: ElectricalStorm 8.7.2004, 18:06
Большое спасибо .... мотаем на ус ...

Вот при компиляции javac версии 1.4 без флагов используется технология HotSpot и JIT
или это специальные программы выполняют стандартный компилятор это не делает ?

Автор: Domestic Cat 8.7.2004, 18:15
При компиляции javac делает небольшие оптимизации (можно ради интереса декомпильнуть class-фаuл и посмотреть).
"Еше" больше oптимизировать можно, компилируя с флагом -O, но я особоu разницы не замечаю.
JIT же, как следует из названия, дополнительно компилирует при запуске JVM (java MyClassName), на 1.4 тоже; причем его оптимизации очень сушественные. Опять-таки, дополнительную оптимизацию дает запуск с флагом -server (java -server MyClassName), например, тогда JIT может "развернуть" цuклы.

Автор: ElectricalStorm 8.7.2004, 18:31
понятно спасибо !

Автор: Domestic Cat 8.7.2004, 19:19
Не за что smile.gif

Ну и вопрос в тему: как сменить иконку java-программы с "Hot Java" на какую-нибудь другую?

Автор: LSD 8.7.2004, 20:53
setIconImage()
У меня нет -Xmn в списке команд sad.gif .
А есть возможность узнать распределение по старому и молодому хипу програмно?

Автор: Domestic Cat 8.7.2004, 21:09
Цитата
setIconImage()


работает не всегда. Меняет ли он иконку на панели задач?

Цитата
У меня нет -Xmn в списке команд.

- в списке (java -X) ее нет, но работает smile.gif

Цитата
А есть возможность узнать распределение по старому и молодому хипу програмно?

Po-moemu, нет. Можно узнать только размер всего хипа.

Автор: LSD 8.7.2004, 21:11
Цитата(Domestic @ 8.7.2004, 21:09)
Меняет ли он иконку на панели задач?

Под виндами меняет и на панели задач и у диалоговых окон для которых это установленно как родительское.

Автор: Domestic Cat 8.7.2004, 21:15
Тогда соррu. На Маке не меняет, зато

-Xdock:icon=logo.gif

работает

Автор: Domestic Cat 9.7.2004, 16:04
Программа:
Код


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JFrame implements ActionListener
{
   private JButton repaint;
   private JButton turnOff;
   private MyPanel area;
   public Test()
   {
       setSize(700, 500);
       Container cp = getContentPane();
       repaint = new JButton("Repaint");
       repaint.addActionListener(this);
       turnOff = new JButton("Turn repainting off");
       turnOff.addActionListener(this);
       area = new MyPanel();
       cp.add(repaint, BorderLayout.NORTH);
       cp.add(area, BorderLayout.CENTER);
       cp.add(turnOff, BorderLayout.SOUTH);
       setDefaultCloseOperation(EXIT_ON_CLOSE);
       setLocationRelativeTo(null);
       setResizable(false);
       setVisible(true);
   }
   
   public static void main(String [] args)
   {
       new Test();
   }
   
   public void actionPerformed(ActionEvent ae)
   {
       if (ae.getSource() == repaint)
       {
           area.repaint();
           System.out.println("Mouse button clicked at " + new java.util.Date());
       }
       else if (ae.getSource() == turnOff)
       {
       }
   }
}

class MyPanel extends JPanel
{
   private Color color;
   private int red, green, blue;
   
   public void paint(Graphics g)
   {      
       red = (red > 200) ? 0 : red + (int) (Math.random() * 40);
       green = (green > 200) ? 0 : green + (int) (Math.random() * 40);
       blue = (blue > 200) ? 0 : blue + (int) (Math.random() * 40);
       color = new Color(red, green, blue);
       g.setColor(color);
       g.fillOval(getWidth() >> 1, getHeight() >> 1, 100, 80);      
   }
}

chto нужно добавить чтобы при нажатии кнопки "Repaint" прекратилась прорисовка овала? Нужно
выключить только repaint события (то есть posle нажатиja на "Turn repainting off" овал не прорисовывается, но дата в консоль выводится esli nazhimat' "Repaint"). Можно:
1. добавлять код в
Код

       else if (ae.getSource() == turnOff)
       {
              // sjuda
       }

2. создавать другие классы
Менять код в программе нельзя.

Автор: Domestic Cat 10.7.2004, 21:39
sad.gif
Ответ простоu:

Код

...
       else if (ae.getSource() == turnOff)
       {
           NullRepainter.install();
       }

...
class NullRepainter extends RepaintManager
{
   public static void install()
   {
       RepaintManager rm = new NullRepaint();
       RepaintManager.setCurrentManager(rm);
   }
   
   public void addInvalidComponent(JComponent c)
   {}
   
   public void addDirtyRegion(JComponent c, int x, int y, int w, int h)
   {}
   
   public void markCompletelyDirty(JComponent c)
   {}
   
   public void paintDirtyRegions()
   {}
}

Автор: Domestic Cat 12.7.2004, 15:29
Код

public class Test
{
   public static void main(String [] arguments)
   {
       String string1 = new String("qwerty");
       String string2 = new String("qwerty");
       // ?
       // ?
       System.out.println(string1 == string2);
   }
}


Какие 2 строки нужно добавить чтобы получить в результате true?
Приравнивать string1 i string2 нельзя.

Автор: Domestic Cat 12.7.2004, 15:46
Имеется в виду, что нельзя использовать выражения типа
Код

string1 = string2;

и
Код

String string3 = string1;
string2 = string3;

Автор: Sun 12.7.2004, 16:35
Код

      string1 = string1.intern();
      string2 = string2.intern();
?

Автор: Domestic Cat 12.7.2004, 17:13
Согласен biggrin.gif


Автор: Domestic Cat 12.7.2004, 17:28
А как узнать сколько было создано обьектов класса Float и Integer после выполнении этоu программы:
Код

public class Test
{
   public static void main(String [] arguments)
   {
       int numIter = (int)(Math.random() * 1000);
       for (int i = 0; i < numIter; i++)
       {
           double random = Math.random();
           if (random < 0.5)
           {
               new Float(1);
           }
           else
           {
               new Integer(1);
           }
       }
   }
}

Автор: Domestic Cat 13.7.2004, 19:48
Ответ опять простой :

java -Xaprof Test

- выдаст количество созданных объектов каждого класса (за все время выполнения программы) и занятое ими место.


Автор: Domestic Cat 14.7.2004, 15:56
Простой бенчмарк:

Код

public class Test
{
   public static void method()
   {
   }
           
   public static void runTest()
   {
       long before;
       long after;
       before = System.currentTimeMillis();
       for (int index = 0; index < 1*1000*1000; index += 1)
       {
       }
       after = System.currentTimeMillis();
       long loopTime = after - before;
       System.out.println("Loop time: " +
                       Long.toString(loopTime) +
                       " milliseconds");
       before = System.currentTimeMillis();
       for (int index = 0; index < 1*1000*1000; index += 1)
       {
           method();
       }
       after = System.currentTimeMillis();
       long methodTime = after - before;
       System.out.println("Method time: " +
                           Long.toString(methodTime) +
                           " milliseconds");
       System.out.println("Method time - Loop time: " +
                           Long.toString(methodTime - loopTime) +
                           " milliseconds");
   }
   public static void main(String[] arg)
   {
       runTest();
   }
}


Частенько я получаю нечто наподобие:

Loop time: 22 milliseconds
Method time: 17 milliseconds
Method time - Loop time: -5 milliseconds

Почему пустoй цикл медленнее чем цикл с вызовом метода ? biggrin.gif biggrin.gif

Еще интереснее станет если изменить метод, например
Код

   public static void method(int x)
   {
         int y = x + 100;
   }

Опять получаем:

Loop time: 22 milliseconds
Method time: 16 milliseconds
Method time - Loop time: -6 milliseconds

Почему цикл с вызовом непустого метода быстрее пустого цикла?

Автор: Domestic Cat 15.7.2004, 15:45
Чуствую приходит шизофрения: сам спрашиваю, сам себе же и отвечаю adv/57.gif

Автор: LSD 15.7.2004, 19:58
Результат довольно нестабильный, после 3-4 запуско все становится на свои места. Я думаю все дело в JIT. Если запускать с -Xint, то loop всегда меньше.

Автор: Domestic Cat 15.7.2004, 20:20
biggrin.gif Да, это дело рук JIT. Если бы method например возвращал константу, то JIT перенес бы тело метода внутрь цикла (method inlining) и таким образом устранил лишний вызов метода. (Если бы метод не был static, и от класса Test наследовал бы другой класс, то JIT бы сделать этого уже не мог).
Здесь в обеих случаях method фактически ничего не делает, поэтому JIT делает инлайнинг метода, то есть оба цикла после компиляции оказываются пустыми, а значит и время выполнения
должно быть одинаковым. То, что оно разное обусловлено случайными факторами.

Автор: Domestic Cat 16.7.2004, 15:48
Ну это совсем уж просто.
Для записи объекта используем сериализацию:
Код

import java.io.*;
public class Test
{
   public static void main(String [] args) throws Exception
   {
       if (args[0].equals("-r"))
       {
           MyObject mo;
           FileInputStream fis = new FileInputStream("object.ser");
           ObjectInputStream ois = new ObjectInputStream(fis);
           mo = (MyObject) ois.readObject();
           ois.close();
           System.out.println(mo.name);
       }
       else if (args[0].equals("-w"))
       {
           MyObject mo = new MyObject();
           FileOutputStream fos = new FileOutputStream("object.ser");
           ObjectOutputStream oos = new ObjectOutputStream(fos);
           oos.writeObject(mo);
           oos.close();
       }
       else return;
   }
}

class MyObject implements Serializable
{
   public String name = "Name";
}


1. Предположим я сохраню 1000 обьектов, после чего может оказаться что нужно добавить новое поле в класс MyObject. После добавления нового поля при попытке чтения ранее сохраненных объектов я получу InvalidClassException. Как обеспечить совместимость версий?

2. Предположим я сохраняю объект в фаил описанным выше методом. Любой злонамеренный
товариш теперь может открыть этот фаил в текстовом редакторе и исправить все что нужно:

Содержимое : srMyObjectLnametjava/lang/String;xptName

Исправлено: srMyObjectLnametjava/lang/String;xptFame

Как предотвратить такую возможность в рамках той же сериализации?

Автор: DarkDS 16.7.2004, 17:31
Что можно менять/добавлять?

Отвечать сразу или подождать вариантов? smile.gif

Автор: Domestic Cat 16.7.2004, 17:42
Ну, здесь можно делать с классом MyObject все что хотите smile.gif

Автор: LSD 16.7.2004, 17:58
Для совместимости версий надо добавить в MyObject поле:
Код
private static final long serialVersionUID = -6849794470754667710L;

где число равно serialVersionUID для оригинального класса. Узнать его можно с помощью утилиты serialver.
Для того чтобы защитится от злыдней которые посягают на наш класс, надо в классе определить 2 метода:
Код

private void writeObject(java.io.ObjectOutputStream out) throws IOException
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

и уже в них например организовать шифрацию/дешифрацию критичной информации (например сделать поля transient и записывать их вручную).

Автор: Domestic Cat 16.7.2004, 18:36
Хороший ответ smile.gif
Кстати внутри методов можно пользоваться defaultWriteObject, defaultReadObject; например defaultWriteObject запишет все не-транзиентные не-static поля. А как сделать так чтобы он записывал только часть не-транзиентных не-static полей (например 2 поля String name и String age, в то время как всего public String полей 20 штук)?

Автор: DarkDS 16.7.2004, 18:43
Как вариант - можно использовать Экстарналайз интерфейс. При этом класс сам отвечает за сохранение и востановление полей smile.gif

Автор: Domestic Cat 16.7.2004, 18:49
Externalizable служит для полного контроля над сериализацией. А если мне нужно просто
настроить default****Object? smile.gif

Автор: LSD 16.7.2004, 19:33
Не вызывать defaultWriteObject и defaultReadObject, а самому записать нужные поля.

Автор: Domestic Cat 16.7.2004, 19:45
biggrin.gif Достаточно дописать поле
Код

private static final ObjectStreamField[] serialPersistentFields =...

и в одномерный массив записать те поля которые нужно сохранить.
При вызове defaultWriteObject будут соxраняться только они.

Код

private static final ObjectStreamField[] serialPersistentFields = {new ObjectStreamField("name", String.class), new ObjectStreamField("myMap", HashMap.class), ...};

Автор: Domestic Cat 17.7.2004, 23:26
Ну а теперь действительно маленький тест (в качестве отдыха biggrin.gif )

1.
Код

Vector vector = new Vector(100);
vector.add(10, new String("string"));


а. Код не скомпилируется
б. При запуске программа добавит в vector элемент на позиции 10
в. При запуске программа добавит в vector элемент на позиции 9
г. При запуске будет bрошена exception
д. Программа выполнится без exception'ов, но vector останется пустым

2.
Код

   static void change (String string, StringBuffer sb)
   {
       string.replaceAll("o", "e");
       sb.replace(5, sb.length(), "suckaz");
   }
   public static void main(String[] args)
   {
       String string = "Mikrosoft";
       StringBuffer sb = new StringBuffer("Mikrosoft");
       change(string, sb);
       System.out.println(string + " or " + sb);
   }


а. Код не скомпилируется
б. При запуске будет брошена exception
в. Mikreseft or Mikrosoft
г. Mikreseft or Mikrosuckaz
д. Mikrosoft or Mikrosoft
е. Mikrosoft or Mikrosuckaz
zh. Mikresoft or Mikrosuckaz

3.
Код

       int  y = 0;
       int i = 0;
       for (; i < 10; i++)
       {
           y++;
           if (y > 4) break;
       }
       System.out.println((y + i));
       
       y = 0;
       i = 0;
       for (; i < 10; )
       {
           i++;
           y++;
           if (y > 4) break;
       }
       System.out.println((y + i));



а. Код не скомпилируется
б. При запуске будет брошена exception
в. 9
9

г. 10.
9.

д. 9
10

е. 8
9

ж 10
10

з 10
8


Автор: Domestic Cat 20.7.2004, 19:40
Ответы :
1. г
2. е
3. д

Автор: Domestic Cat 20.7.2004, 20:05
А каково точное значение цвета (RGB) у TextField бакграунда при выделении для
MetalLookAndFeel ? Для получения ответа cоздавать TextField нельзя.

Автор: redrick 21.7.2004, 00:41
Код

try {
           UIManager.setLookAndFeel("defaultMetalTheme"); // или как там класс называется
           SwingUtilities.updateComponentTreeUI(this);

} catch (Exception e) {
}

Color clr = UIManager.getColor("textHighlight");

clr.getRGB();


эм, где подвох ?

Автор: Domestic Cat 21.7.2004, 01:04
smile.gif Да нигде smile.gif Можно и так:
Код

import java.awt.Color;
import java.util.*;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.SwingUtilities;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.UIDefaults;

public class Test
{

   public static void main(String[] args) throws Exception
   {
       try
           {
               UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
           }
           catch (Exception e)
           {
           }

       List allValues = new ArrayList();
       UIDefaults defaults = UIManager.getDefaults();
       Enumeration e = defaults.keys();
       while (e.hasMoreElements())
       {
           Object key = e.nextElement();
           Object value = defaults.get(key);
           if (value instanceof Color)
          {
               allValues.add(key + " = " + value);
           }
       }

       Collections.sort(allValues);
       for (int i=0; i<allValues.size(); i++)
       {
           System.out.println(allValues.get(i));
       }
   }
}


- печатает все дефаулты

Автор: redrick 21.7.2004, 01:35
да, полезная вещь :-)

Автор: Domestic Cat 21.7.2004, 16:50
Как сделать чтобы этот миди-плеер крутил миди в цuкле (loop)? Можно добавить один метод, исправить констрактор и добавить implements

Код

import java.io.*;
import javax.sound.midi.*;

public class MidiPlayer
{

   private Sequencer sequencer;
   private boolean loop;
   private boolean paused;

   public MidiPlayer()
   {
       try {
           sequencer = MidiSystem.getSequencer();
           sequencer.open();
       }
       catch ( MidiUnavailableException ex)
       {
           sequencer = null;
       }
   }

   public Sequence getSequence(String filename)
   {
       try
       {
           return getSequence(new FileInputStream(filename));
       }
       catch (IOException ex)
       {
           ex.printStackTrace();
           return null;
       }
   }


   public Sequence getSequence(InputStream is)
   {
       try
       {
           if (!is.markSupported())
           {
               is = new BufferedInputStream(is);
           }
           Sequence s = MidiSystem.getSequence(is);
           is.close();
           return s;
       }
       catch (InvalidMidiDataException ex)
       {
           ex.printStackTrace();
           return null;
       }
       catch (IOException ex)
       {
           ex.printStackTrace();
           return null;
       }
   }


   public void play(Sequence sequence, boolean loop)
   {
       if (sequencer != null && sequence != null && sequencer.isOpen())
       {
           try
           {
               sequencer.setSequence(sequence);
               sequencer.start();
               this.loop = loop;
           }
           catch (InvalidMidiDataException ex)
           {
               ex.printStackTrace();
           }
       }
   }

   public void stop()
   {
        if (sequencer != null && sequencer.isOpen())
        {
            sequencer.stop();
            sequencer.setMicrosecondPosition(0);
        }
   }


   public void close()
   {
        if (sequencer != null && sequencer.isOpen())
        {
            sequencer.close();
        }
   }


   public Sequencer getSequencer()
   {
       return sequencer;
   }


   public void setPaused(boolean paused)
   {
       if (this.paused != paused && sequencer != null && sequencer.isOpen())
       {
           this.paused = paused;
           if (paused)
           {
               sequencer.stop();
           }
           else
           {
               sequencer.start();
           }
       }
   }


   public boolean isPaused()
   {
       return paused;
   }

}


Автор: Domestic Cat 26.7.2004, 15:23
Ответ:

http://java.sun.com/j2se/1.3/docs/api/javax/sound/midi/MetaEventListener.html

Другой вопрос: чтобы скопировать файл "обычный" подход - прочитать его содержимое и
записать в другой файл. (см например http://www.experts-exchange.com/Programming/Programming_Languages/Java/Q_10245809.html)

А как это сделать в одну строчку не читая содержимого файла?

Автор: LSD 26.7.2004, 19:07
Без использования команд ОС?

Автор: Domestic Cat 26.7.2004, 19:10
Ага, забыл про такую возможность. Без Runtime.exec(), в общем, без ОС.

Автор: ElectricalStorm 30.7.2004, 10:25
Не совсем уверен что это то
но метод в одну строчку smile.gif

Код

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile {

   public static void main(String[] args) throws IOException {
       long t = System.currentTimeMillis();
       copyFile("c:\\file", "c:\\copy_file");
       System.out.println(System.currentTimeMillis() - t);
   }

   public static void copyFile(String infile, String outfile) throws IOException {
       new FileOutputStream(outfile).getChannel().transferFrom(
               new FileInputStream(infile).getChannel(),
               0,
               new FileInputStream(infile).getChannel().size());
   }

}


вот стандратный метод ( правда немного надуманный smile.gif ) который для больших файлов работает быстрее
Код

public static void copyFile(String infile, String outfile) throws IOException {
       FileChannel fcin =  new FileInputStream(infile).getChannel();
       FileChannel fcout = new FileOutputStream(outfile).getChannel();

       for(ByteBuffer bb  = ByteBuffer.allocateDirect((int)Math.pow(2D, 16D));
                 fcin.read((ByteBuffer)bb.clear()) != -1;
                 fcout.write((ByteBuffer)bb.flip()));
}

Автор: Domestic Cat 30.7.2004, 15:10
smile.gif Полезная вешь - nio biggrin.gif

Вопрос: в таком коде:
Код

MyObject obj1 = new MyObject();
MyObject obj2 = new MyObject();
myMethod(obj1, obj2);
...

public void myMehtod(MyObject o1, MyObject o2)
{
...
}

obj1 и obj2 передаются по значанию (by value) или по ссылке (by reference)?

Автор: AntonSaburov 30.7.2004, 16:27
Цитата
Полезная вешь - nio

Если бы FAQ внимательнее почитали, то сразу бы нашли smile.gif

Автор: Domestic Cat 30.7.2004, 16:33
Цитата
Если бы FAQ внимательнее почитали, то сразу бы нашли


Кто? Я собственно и имел в виду transferFrom smile.gif


Added:

Вопрос остается - obj1, obj2 передаются по ссылке или по значению ?

Автор: ElectricalStorm 2.8.2004, 12:34
мне кажется по ссылке

Автор: Domestic Cat 2.8.2004, 15:58
А я думаю, что Java всегда все передает по значению smile.gif

Автор: AntonSaburov 2.8.2004, 17:27
Цитата
А я думаю, что Java всегда все передает по значению

Ну это уже спор достаточно теоретический IMHO.
В принципе obj1 и obj2 являются ссылками и вот сами ссылки передаются как значения - они копируются.

Автор: Domestic Cat 2.8.2004, 17:47
Скорее так: в Java "pass-by-reference" обрело несколько другой смысл, чем, например, в C++.

В C++ код

Код


void swap(SomeType& arg1, SomeType& arg2)
{
 SomeType temp = arg1;
 arg1 = arg2;
 arg2 = temp;
}

SomeType var1 = ...;
SomeType var2 = ...;
swap(var1, var2);



изменит оригинальные var1, var2. В Java этот же самый код изменит локальные arg1, arg2, тогда как var1 и var2 не изменятся. Эсли называть C++-шный вариант "pass-by-reference", то Java - 100% pass-by-value.

Когда говорят о "передаче по ссылке" в, то имеется в виду cкорее нечто вроде
передачи поинтера (правда, более "безопасного" поинтера); причем называется этот
поинтер "ссылкой".

Автор: DarkDS 2.8.2004, 20:22
Цитата(Domestic @ 2.8.2004, 17:47)
В Java этот же самый код изменит локальные arg1, arg2, тогда как var1 и var2 не изменятся.

Не скажи.
По твоему что выдаст такой код?
Код

import java.util.*;

public class Test
{
public static void main(String [] args) throws Exception
{
 List l = new LinkedList();

 Test t = new Test();
 
 t.add(l);
 
 Iterator iterator = l.iterator();
 while( iterator.hasNext() )
 {
  System.out.println(iterator.next());
 }  
}

private void add( List test )
{
 test.add("1");
 test.add("2");
 test.add("3");
 test.add("4");
}
}

Автор: Domestic Cat 2.8.2004, 20:33
Здесь ты изменяешь ОБЪЕКТ ( l ), пользуясь поинтером ( test, буду называть его ссылкой как
принято). Но изменить sam test НЕЛЬЗЯ. Например, метод:
Код

import java.util.*;

public class Test
{
public static void erase(Object obj)
{
   obj = null;
}

public static void main ( String args [])
{
  Object myObject = new Object();
  erase(myObject);
  System.out.println(myObject);
}
}


- он напечатает хэш код, не null. Если бы myObject был передан по ссылке, мы бы получили null.

Автор: Domestic Cat 2.8.2004, 20:45
1. Передача по ссылке:

методу передается "оригинальный" поинтер;
например
Код


Object a;
f(a);

..
void f(Type& b)
{
    b = NULL;
}



Здесь 'а' принимает другое (локальное) имя ('b'), но она "синхронизирована" с b - если ее занулить, то 'а' тоже будет null.

a (она же b) ----> Object

2. По значению.
Код

Object a = new Object ();
f(a);

..
void f(Object b)
{
    b = null;
}


Ссылка копируется - то есть, у нас есть уже 2 ссылки на объект.
a-----> Object <-----b

С объектом можно делать что угодно, но ссылки "асинхронны" - зануление b никак не влияет на
а.

Автор: DarkDS 2.8.2004, 23:05
Цитата(Domestic @ 2.8.2004, 20:33)
Здесь ты изменяешь ОБЪЕКТ ( l ), пользуясь поинтером ( test, буду называть его ссылкой как
принято). Но изменить sam test НЕЛЬЗЯ.

Ты будешь смеятся, но я это знаю. smile.gif Просто я хотел сказать что в яве не 100% pass-by-value. Иначе бы этот код вообще не работал smile.gif

Автор: redrick 3.8.2004, 02:26
pass-by-value точно нет, скорее pass-by-reference. Хотя я бы здесь присоединился к AntonSaburov. Действительно, вроде бы все представляют, что происходит, просто разные слова говорят.

Автор: Domestic Cat 3.8.2004, 15:24
smile.gif ТЕм не менее, и примитивы и ссылки в Java передаются по значению - если сравнивать со смыслом "передача по ссылке" в C++.

Автор: DarkDS 3.8.2004, 18:54
Более точно - в ява все передается по защищенному указателю. ТО есть при изменении данных внутри объекта изменения сохранятся. при попытки изменения указателя на обект (b = null;) изменений не произойдет smile.gif

Автор: Domestic Cat 3.8.2004, 19:32
Ну вот с этим уже трудно не согласиться smile.gif

Автор: Domestic Cat 4.8.2004, 17:41
А что выдаст эта программа ? smile.gif

Программу не запускать!!! smile.gif
Код

import java.nio.*;

public class test
{

 public static void main(String[] args)
 {
   try
  {
     float[] floats =
     {
       6.612297E-39F, 9.918385E-39F, 1.0193785E-38F, 1.092858E-38F,
       1.0469398E-38F, 9.183596E-39F
     };

     ByteBuffer bb = ByteBuffer.allocate(floats.length * 4);

     FloatBuffer fb = bb.asFloatBuffer();
     fb.put(floats);

     CharBuffer cb = bb.asCharBuffer();
     System.out.println(cb.toString());

     }
    catch (Exception e)
    {
        System.out.println(e.getMessage());
        e.printStackTrace();
   }
 }
}

Автор: AntonSaburov 4.8.2004, 18:04
Можно было догадаться, что фраза из 12 букв. На ум приходит "Hello world!".
Потому как байтов 24, а символ из двух байт.

Каюсь, потом запустил. Повеселился от души smile.gif

Автор: redrick 5.8.2004, 03:47
Код

0048 0064 006C 006C 006F 0020 0077 006F 0072 006C 0064 0021
H    d    l    l    o         w    o    r    l    d    !


- ошибка во втором символе. Вот только с nio я никогда не работал, может тут каие ексепшены посыпятся, хотя врядли....

Автор: Domestic Cat 5.8.2004, 15:41
smile.gif
Код

    ... 0065 ...
    ... e   ...

Автор: redrick 5.8.2004, 21:23
ну, это понятно, я просто копипайстил значения float и переводил в hex в соответствии со стандартом

но вопрос я так понимаю всё еще не отвечен....

Автор: Domestic Cat 5.8.2004, 21:28
Почему? Вроде все правильно smile.gif

Автор: Domestic Cat 5.8.2004, 21:48
Вопрос:

Можно ли массив

Код

int arrayToSort[] = {1, 3, 5, 12, 6, 8, 10, 23, 24, 29, 28, 39, 46, 78, 101, 102, 103,
203, 204, 209, 212, 233, 231, 244, 344, 444, 555, 668, 778, 898, 900};


отсортировать быстрее (не руками smile.gif а используя алгоритм ), чем это сделает Arrays.sort()?

Автор: redrick 5.8.2004, 23:14
пузырьком, проверить правда прямо сейчас не могу

Автор: Domestic Cat 7.8.2004, 20:31
Ага, по идее и пузырек, и insertion sort дадут О(n).

Более интересный вопрос:

Каково практическое применение метода hashCode() из java.lang.Object?

Автор: LSD 7.8.2004, 20:48
Hashtable, HashMap.

Автор: Domestic Cat 7.8.2004, 21:03
Да, но более конкретно? Нужно ли (и для чего) делать override этого метода в классах,
объекты которых я собираюсь поместить в ту же HashMap?

Автор: LSD 8.8.2004, 08:40
По рекомендациям Sun нужно переопределять этот метод совместно с equals(), так чтобы для любых обектов для которых equals() == true хэш код тоже был бы равен. Это требуется если нужно определить сравнение отличное от унаследованного. Например для объекта Entry который представляет элемент Map (т.е. пару ключ значение), equals() должен сравнивать только ключи и соответственно хэш код надо брать от ключа.
Вообще хороший хэш код должен давать равномерное распределение кодов для всего множества объектов, или его некой части которая встречается в конкретной задаче.

Автор: Domestic Cat 9.8.2004, 15:36
Да. Есть методы получения равномерного распределения хэш кодов.
Кроме того, не было бы полезно, если бы скажем, слово "язык" имело хэш код близкий
к кодам слов "язук", "юзук" и т п smile.gif (Хотя для спеллинга другие методы есть)

Автор: Domestic Cat 9.8.2004, 16:11
Ну, це мае бути просто:

Код

int a = 100;
int b = -233;
System.out.println("Before:");
System.out.println("a = " + a);
System.out.println("b = " + b);

int temp = a;
a = b;
b = temp;

System.out.println("After:");
System.out.println("a = " + a);
System.out.println("b = " + b);


Как "перебросить" a и b, не используя вспомогательных переменных?

Автор: Ignat 9.8.2004, 17:38
Цитата(Domestic @ 9.8.2004, 17:11)
Как "перебросить" a и b, не используя вспомогательных переменных?


Код
int a = 100;
int b = -233;
System.out.println("Before:");
System.out.println("a = " + a);
System.out.println("b = " + b);

a+=b;
b=a-b;
a=a-b;

System.out.println("After:");
System.out.println("a = " + a);
System.out.println("b = " + b);

так?

Автор: Domestic Cat 9.8.2004, 17:53
Я бы предпочел более красивый вариант

Код

a = a ^ b;
b = a ^ b;
a = a ^ b;


Хотя для double'ов это не пройдет
smile.gif

Автор: AntonSaburov 9.8.2004, 17:56
Ну и я тоже внесу свою лепту smile.gif

1. Какие из объявлений переменных неверные ?
a) int 99year;
b) int year99;
c) int hello#;
d) int #hello;
e) int hello$;
f) int $hello;

2. Какое сообщение об ошибке будет при компиляции совершенно пустого файла ?

Автор: Domestic Cat 9.8.2004, 18:00

Переменные я "угадал", а вот с пустым файлом ты меня подловил smile.gif

Автор: AntonSaburov 9.8.2004, 18:07
Пишем ответы

1. НЕверные объявления a), c), d)

2. Никаких сообщений не будет - просто не будет результата компиляции, файла с расширением class.

Автор: Domestic Cat 9.8.2004, 18:36
Можно ли из Java-программы вызвать метотоды, содержащиеся в файле
(ращирениe - не ".java"). Содержание файла таково:

Код

playerDoorTriggerTouch()
{
   moveDoor(180);
}

playerDoorTriggerRelease()
{
   moveDoor(0);
}

moveDoor(int y)
{
   speed = .5f;
   moveYTo(door1a, y, speed);
   moveYTo(door1b, y, speed);
   moveYTo(door1c, y, speed);
   moveYTo(door1d, y, speed);
   moveYTo(door1e, y, speed);
   moveYTo(door1f, y, speed);
   moveYTo(door1g, y, speed);
}


Какой самый простой способ?

Автор: Domestic Cat 9.8.2004, 21:04
Чуствую, круто взял smile.gif. Ответ тут:

http://www.beanshell.org/

Другой вопрос:

Код

public class Test
{
   public static void main(String [] args)
   {
       float a = 1296856321;
       long b = 1296856301;
       long c = 1296856308;
       if (a == b) System.out.println("a==b");
       if (c == b) System.out.println("c==b");
   }
}


Каков результат?

Автор: DarkDS 10.8.2004, 11:51
а==б
Так как конвертация во флоат будет с потерей точности. В данном случае
а = 1.29685632E9
б так же будет 1.29685632E9

Автор: Domestic Cat 10.8.2004, 22:25
smile.gif

Известно, что всегда можно сделать такой cast:
Код

SomeType someType;
Object object = someType;


А что в Java обладает способностю быть приведенным к любому типу?

Код

SomeType someType = (SomeType) ?;
OtherType otherType = (OtherType) ?;

Автор: DarkDS 11.8.2004, 12:14
null smile.gif

Автор: Domestic Cat 11.8.2004, 15:21
thumbs-up.gif

Другая задачка, менее связанная с Java, но мне ндравится smile.gif

Итак: Противоракетная система Patriot имеет внутренний счетчик частотой 10 Гц. Для определения времени в секундах значение счетчика умножается на 1/10.
Значение 1/10 хранится как 24-битный float ( smile.gif ). Положение ракеты определяется по
последним значениям радара.
Система работает в течение 100 часов. Радар засек ракету Skud, скорость которой
2000 м/с. Какова будет ошибка определения положения ракеты системой Patriot
(в метрах)?

// Реальная история: 25 февраля 1991 года, Дхаран, Саудовская Аравия.

PS. За первый правильный ответ с точностью до метра дам +1 *

--------------
* Subject to change. Only residents of USA and Canada are eligible. smile.gif

Автор: LSD 11.8.2004, 21:27
Цитата(Domestic @ 10.8.2004, 22:25)
А что в Java обладает способностю быть приведенным к любому типу?

И что же можно привести и к int и к Object? smile.gif

Не известна погрешность самого радара.

Автор: Domestic Cat 11.8.2004, 21:33
Цитата
И что же можно привести и к int и к Object? 


Подловил ;)

"The null reference initially has no runtime type, but may be cast to any type
(JVM spec, 3.4). "

Под "типом" подразумеваются : "class types, array types, and interface types"

Цитата
Не известна погрешность самого радара


Считаем, что погрешность радара = 0 smile.gif.

Автор: redrick 12.8.2004, 00:13
Цитата(Domestic @ 11.8.2004, 15:21)
Значение 1/10 хранится как 24-битный float ( smile.gif ).

давайте определимся, что такое float для начала =)

Автор: Domestic Cat 13.8.2004, 15:15
Цитата
давайте определимся, что такое float для начала =)


Нууу... Подсказка нужна? smile.gif

Записать 1/10 в двоичной форме, оставить 23 бита (первый бит подразумевается) ...

Можно ради интереса посмотреть какие будут 24, 25, 26 ... биты

Автор: redrick 13.8.2004, 18:41
да не =) это понятно, просто float разные бывают и от этого зависит, что собственно в этих битах будет. Стандарта 3-байтового float я не нашёл =( хотя так тоже конечно можно попробовать прикинуть

Автор: Domestic Cat 13.8.2004, 18:43
Цитата
...просто float разные бывают и от этого зависит...


Да забудь ты уже про флоат smile.gif

... 1/10 в двоичной форме, оставить 23 бита...

Автор: redrick 13.8.2004, 19:20
ну тогда по первым предворительным =) подсчетам 64 метра

(считая что експоненты нет вообще =\ )

Автор: Domestic Cat 13.8.2004, 19:40
Желательно расчеты выложить, но отевет на самом деле побольше... раз в 5- 10 smile.gif

Автор: redrick 13.8.2004, 20:11
ну чтож,

1/10 = 6710886,4 / 2^26
6710886 / 2^26 = 110 0110 0110 0110 0110 0110 / 2^26

итого

1/10 = 0,00 0110 0110 0110 0110 0110 0110
с точностью до 26 знака после запятой

итого ошибка 110 / 2^26 = 6 / 67108864 = 0,0000000894069671630859375

0,0000000894069671630859375 * 360000 * 200 = 6,43

и того меньше.....


я всё таки не понимаю, неужели не очевидно, что от того в каком виде там число храниться всё и зависит ?

или я как всегда что то не понимаю

Автор: Domestic Cat 13.8.2004, 20:19
// Удалил по причине арифметической ошибки sad.gif

---------------
А здесь можно об этом прочитать (статья уже напрямую связана с Java) smile.gif

http://www.rrs.ru/articles.html?article=52

Автор: redrick 13.8.2004, 20:29
здесь

итого ошибка 110 / 2^26 = 6 / 67108864 = 0,0000000894069671630859375

я отсёк первые 23 и оставил 24-ый, 25-ый и 26-ой


опс.... я потерял порядок, когда считал число секунд... - не умножил на 10 (10 Гц) =( и ракета во второй раз у меня летела со скоростью 200 м/с вместо 2000 м/с =(( - так что в результате 643 (4) будет....



Автор: redrick 13.8.2004, 21:14
на мой взгляд самое интересное было в конце

Цитата

Организация взаимодействия построена на базе электрического явления, называемого емкостным сопротивлением. Передача информации между отдельными чипами в данном случае происходит без использования кабелей и контактов, которые присутствуют в традиционных компьютерных платах. Если специалистам Sun удастся организовать на основе этой технологии эффективный рабочий процесс, это может оказать фундаментальное воздействие на весь дальнейший ход проектирования перспективных компьютеров.


впервые слышу о такой альтернативе - токлько об "квантовых" и "оптоэлектронных" знал

Автор: Domestic Cat 13.8.2004, 21:18
Ух, я ошибся, вместо умножить на (1 + 0.5) поделил на него, да еще и разделил на 2^23 а не 2^24 ; надо было так:

1/10 (точно) - 1/10 (23-bit) = 0.0.....11 = 2^(-24) + 2^(-25) = 2^(-24) * (1 + 0.5)

2000 * 3600 * 10 * 100 * (1 + 0.5)/ 2^24 ~ 643 метра

Автор: Domestic Cat 13.8.2004, 21:32
Цитата

впервые слышу о такой альтернативе - токлько об "квантовых" и "оптоэлектронных" знал


По этому поводу вот статейка

http://research.sun.com/async/RelatedSites/Versions/SunUnveils.html

Автор: redrick 14.8.2004, 00:36
спасибо - но тут тоже больше реклама вроде как... хотя наверно больше никто и не скажет пока =)

Автор: Domestic Cat 14.8.2004, 22:51
Кстати, с точностью до метра результат будет иной: нужно учитывать еще и
28, 29 биты:

0.0....11001100... - 1/10(23-bit) ~ 2^(-24) * (1 + 1/2 + 1/16 + 1/32) = 2 ^ (-24) * 1.59375

Так что ошибка будет ~ 683.96 метров.

Автор: Domestic Cat 15.8.2004, 01:13
Цитата

хотя наверно больше никто и не скажет пока =)

Ну почему же? Вот тут:

http://research.sun.com/async/Publications/KPDisclosed/sml2003-0241/sml2003-0241.pdf

А здесь вообще на 140 страниц:
http://research.sun.com/research/techrep/2002/abstract-107.html

Автор: Domestic Cat 16.8.2004, 15:48
Ок, задача такая:

1. Можно использовать только операторы: ~, |, &, ^, !=, ().
Соответственно, остальные использовать нельзя (<, > ,<=, >= ...)
2. Можно использовать только 2 методa из класса StringBuffer:

charAt()
setCharAt()

Дана произвольная строка, скажем "The Java Programming Language"
Напечатать:
а. THE JAVA PROGRAMMING LANGUAGE
б. the java programming language
в. tHE jAVA pROGRAMMING lANGUAGE

// Можно использовать также =, ++, length()

Автор: DarkDS 16.8.2004, 15:57
А length и ++ пользовать можно?

Автор: Domestic Cat 16.8.2004, 16:58
Можно:

=, ++, length()

smile.gif


Автор: DarkDS 16.8.2004, 20:22
a)
Код

StringBuffer buffer = new StringBuffer("The Java Programming Language");
for ( int i = 0; (i ^ buffer.length()) != 0; i++ )
{
if ( (buffer.charAt(i)&32) != 0 )
 if ( (buffer.charAt(i)&~32) != 0 )
  buffer.setCharAt( i, (char)(buffer.charAt(i)&~32) );
}
System.out.println(buffer);

b)
Код

StringBuffer buffer = new StringBuffer("The Java Programming Language");
for ( int i = 0; (i ^ buffer.length()) != 0; i++ )
{
if ( (buffer.charAt(i)&~32) != 0 )
 buffer.setCharAt( i, (char)(buffer.charAt(i)|32) );
}
System.out.println(buffer);

c)
Код

StringBuffer buffer = new StringBuffer("The Java Programming Language");
for ( int i = 0; (i ^ buffer.length()) != 0; i++ )
{
if ( (buffer.charAt(i)&32) != 0 )
{
 if ( (buffer.charAt(i)&~32) != 0 )
  buffer.setCharAt( i, (char)(buffer.charAt(i)&~32) );
}
else if ( (buffer.charAt(i)&~32) != 0 )
 buffer.setCharAt( i, (char)(buffer.charAt(i)|32) );
}
System.out.println(buffer);

Добавлено @ 20:28
Объяснение:
Как известно ^ это XOR, то есть исключающее или (то есть если побитово сравнивать, то остаются биты, которые не равны).
Это значит что (i ^ buffer.length()) != 0 будет правдой тогда и только тогда, когда и = длинне буфера.

Автор: Domestic Cat 16.8.2004, 20:44
У меня (есессно) аналогичное решение:
Код

class Reverser
{
   private static int SPACE = ' ';
   private StringBuffer sb;

   public Reverser(StringBuffer sb)
   {
       this.sb = sb;
   }
   
   public void print()
   {
       System.out.println(sb);
   }
   
   public void makeAllUpperCase()
   {
       for (int i = 0; i != sb.length(); i++)
       {
           if ( (sb.charAt(i) ^ SPACE) != 0)
           {
                  sb.setCharAt(i, (char) (sb.charAt(i) & (~SPACE)));
           }
       }
   }
   
   public void makeAllLowerCase()
   {
       for (int i = 0; i != sb.length(); i++)
       {
           if ( (sb.charAt(i) ^ SPACE) != 0)
           {
                  sb.setCharAt(i, (char) (sb.charAt(i) | SPACE));
           }
       }
   }
   
   public void reverseCase()
   {
       for (int i = 0; i != sb.length(); i++)
       {
           if ( (sb.charAt(i) ^ SPACE) != 0)
           {
                  sb.setCharAt(i, (char) (sb.charAt(i) ^ SPACE));
           }
       }
   }
}


smile.gif

Автор: DarkDS 16.8.2004, 21:09
i != sb.length() ХА! Так не спортивно smile.gif

Автор: Domestic Cat 16.8.2004, 21:11
Цитата
i != sb.length() ХА! Так не спортивно


Ну дык по правилам же? smile.gif

---------------------------------

Кстати, почему в ascii символ DEL имеет код 127, тогда как остальные аналогичные символы имеют код 0 - 31 ? wink.gif

Автор: DarkDS 16.8.2004, 21:24
Дык... Он же 2^7.. То есть покрывает всю нерасширенную таблицу.
| с ним всегда будет 1

Автор: Domestic Cat 16.8.2004, 21:30
Насколько я знаю, некое время назад smile.gif ascii переводился в
бинарный формат и отображался на бумаге в виде дырочек -
1 - дырка, 0 - не дырка. Чтобы удалить символ на перфоленте,
и сделали DEL = 127 = 1111111 - он выбивал все семь дырок.

Автор: redrick 16.8.2004, 21:34
=)))))

Автор: DarkDS 16.8.2004, 21:57
Уточнение: На перфокартах smile.gif))
На перфоленте было комбинацией дырок (то есть там был квадрат с которого считывались дырки...)

Автор: Domestic Cat 16.8.2004, 22:20
smile.gif Опечатка.

А почему данный код не бyдет работать? И что сделать чтобы он заработал?

Код

String string = "somedir:somestuff";
String result = string.replaceAll(":", "\");

Автор: redrick 16.8.2004, 22:30
ну если str определена выше по тексту, то должен работать... ну и слэш наверно удвоить надо

Автор: Domestic Cat 17.8.2004, 15:20
Эх... попробуй удвоить smile.gif Заработает?

Автор: AntonSaburov 17.8.2004, 16:04
Забудем об опечатке: Объявлено string а используем str.replaceAll().

Вообщем-то надо 4 слеша поставить.
replaceAll() использует синтаксис регулярных выражений и один слеш (если удвоить) будет воспринят отнюдь не как слеш (читайте regular expression)

Автор: Domestic Cat 17.8.2004, 16:19
Опечатку исправил smile.gif

В replaceAll() регулярным выражением является только ":", а второй аргумент - обычный
String smile.gif.
Объяснение здесь такое: чтобы вставить в String слэш, нужно писать "\\".
Это будет интерпретировано как "\", и в процессе замены ":" на "\"
мы получим строку "somedir\somestuff" - с ошибкой! Поэтому ":" нужно заменять на 2
слэша - "\\\\". Это будет понято как "\\", и после замены мы получим "somedir\\somestuff"
- здесь уже все ок.

Автор: redrick 17.8.2004, 16:28
да, а ведь точно... я на этом даже както напарывался уже =)

Автор: Domestic Cat 17.8.2004, 16:57
Next:

Нaписать программу, которая, соединившись с сервером 69.64.33.189, из полученного респонса вытянет и напечатает текст самой себя (можно в неформатированном виде) smile.gif

Автор: Domestic Cat 18.8.2004, 15:59
Тут я немного смошенничал smile.gif
Код

//thisIsTheAnswer
import java.io.*;
import java.net.*;

public class Test
{
    public static void main(String [] args) throws Exception
    {
         URL url = new URL("http://forum.vingrad.ru/index.php?showtopic=24799&st=225");
         InputStream content = url.openConnection().getInputStream();
         
         Thread.sleep(10000); // ждем загрузки
         int bytes = content.available();
         byte[] array = new byte[bytes];
         content.read(array);
         
         StringBuffer text = new StringBuffer();
         for (int i = 0; i < bytes; i++)
         {
                text.append((char) arr[i]);
         }
         int i1 = text.indexOf("thisIsTheAnswer");
         int i2 = text.indexOf("theEndOfTheAnswer", i1);
       
         String result = text.substring(i1, i2);
         System.out.println(result);
     }    
} //theEndOfTheAnswer


Автор: redrick 18.8.2004, 16:29
ну знаете =)) ... кстати, а кто может накатать код программы, которая выводит свой сорс, но без всяких коннектов к серверам, и даже без открытия файла - т. е. из IO функций только println используется ?

Автор: Domestic Cat 18.8.2004, 16:58
Код

class Test
{
    static public void main(String[] args)
   {
        String s = "class Test{static public void main(String[] args){String s=; System.out.print(s.substring(0,55)+(char)34+s+(char) 34+s.substring(55));}}";
 System.out.print(s.substring(0,55)+(char)34+s+(char)34+s.substring(55));
   }
}


=)
Ну а если форматирование убрать, то получится в точности она же.

Автор: redrick 18.8.2004, 17:35
не проверяю - верю =)
просто в свое время я долго не мог понять как это все работает - не укладывалось в голове : "раз программа выводит сама себя, то то, что она выводит тоже должно быть такой программой и т. д. и получается на вроде бесконечной рекурсии". Софизм основан на том, что данные в программе можно повторно использовать... вроде так =)

Автор: Domestic Cat 18.8.2004, 18:41
Код

import java.io.*;
class Test
{
   static public void main(String[] arguments) throws Exception
   {
       File file = new File("text.txt").getAbsoluteFile();
       FileInputStream fis1 = new FileInputStream (file);
       System.out.println((char)fis1.read()); // 1
       FileInputStream fis2 = new FileInputStream ("text.txt");
       System.out.println((char)fis2.read()); // 2
   }
}


Структура директорий такая:

text.txt
Desktop/ text.txt Test.class

Файл "text.txt" в Desktop содержит текст "1", файл в паренте - "2".
Если я запускаю код из Desktop, я получу:
1
1
Если я запущу код из парентa:

java -Duser.dir=(здесь полный путь)/Desktop/ Test

- что я получу и почему?

Автор: redrick 18.8.2004, 19:05
предполагаю, что так :
Код

1
2


за первый ответ ручаюсь т. к.
Цитата

By default the classes in the java.io package always resolve relative pathnames against the current user directory. This directory is named by the system property user.dir, and is typically the directory in which the Java virtual machine was invoked.


насчет второго только предполагаю (считаю, что VM при создании FileInputStream ищет в директории, откуда была запущена), т. к. в доках не нашел, написано только, что
Цитата

What files are available depends on the host environment


кстати, почему оно будет работать вообще ? VM разве будет искать Test.class и в user.dir ? (считаем, что Desktop в path нет)

Автор: Domestic Cat 18.8.2004, 19:29
user.dir устанавливает текущую рабочую директорию, так что JVM должна искать там и
на CLASSPATH'е. По идее, и FileInputStream дoлжен читать Desktop/text.txt smile.gif
Но читать он будет второй файл (Bug ID: 4117557).

Автор: redrick 19.8.2004, 15:44
о как =)
да, будем знать, что ещё и в Bug Reports надо заглядывать =) javadoc-ом уже не проживешь =)

Автор: Domestic Cat 19.8.2004, 22:01
Цитата(redrick @ 19.8.2004, 06:44)
о как =)
да, будем знать, что ещё и в Bug Reports надо заглядывать =) javadoc-ом уже не проживешь =)

smile.gif

Код

class A
{
     A()
     {    
            this.show();  
     }
     
      void show()
     {    
            System.out.println("Base Class");    
     }
}

class B extends A
{
      B() { }

      void show()
     {
           System.out.println("Derived Class");
     }
}

public class Test
{
     public static void main(String args[])
     {  
           System.out.println("This is Main");
           new B();
     }
}


Код

#include <iostream>

using namespace std;

class A
{
 public:
 
   A()
   {  
       this->show();  
   }
   
   virtual void show()
   {  
       cout << "Base Class" << endl;  
   }
};

class B : public A
{
 public:
 
   B() {  }
   
   void show()
   {  
       cout << "Derived Class" << endl;  
   }  
};

int main(void)
{
   cout << "This is main" << endl;  
   B test;
}


Вопрос: в чем состоит вопрос?

Автор: redrick 19.8.2004, 22:47
с ходу не сообразил, полез в книжки, ну и =)


Java Language Specification
Second Edition
Цитата

Unlike C++, the Java programming language does not specify altered rules for method dispatch during the creation of a new class instance. If methods are invoked that are overridden in subclasses in the object being initialized, then these overriding methods are used, even before the new object is completely initialized. Thus, compiling and running the example:


class Super {
Super() { printThree(); }
void printThree() { System.out.println("three"); }
}




class Test extends Super {
int three = (int)Math.PI;            // That is, 3
public static void main(String[] args) {
  Test t = new Test();
  t.printThree();
}
void printThree() { System.out.println(three); }
}

produces the output:

0
3




т. е. будет

Derived Class


насчет С++ : думаю будет вывод Base Class т. к. там вроде все по человечески и у Стауструпа не оговорено иначе =)


Автор: Domestic Cat 19.8.2004, 22:51
Насколько я понимаю, в C++ нельзя вызвать overridden метод, если объект еще не создан
(как в этом случае - из конструктора). А в Java можно smile.gif

Автор: redrick 20.8.2004, 04:09
ну в общем - насчет Java там все доступно написано в спецификации =)

а насчет С++ - собственно все так и есть, только имхо тут фраза нельзя "вызвать overridden метод" не очень подходит, т. к. фактически он и не пытается вызваться - вызывается метод базового класса.
На мой взгляд это всё таки логичнее : вызывается конструктор базового класса, из него вызывается метод - естественно искать его в этом же классе, тем более, что в этот момент наследник ещё не создан. Хотя с другой стороны создатели Java тоже правы - вроде как дополнительная возможность, но вот нужна ли она ? Ведь они итак навырезали из C++ кучу всего дабы "упорядочить и упростить", да вот не забыли такую заморочку вставить - зачем ?

а вот насчет того, что это совсем нельзя в С++ я не уверен - просто я не знаю с ходу как... можт кто и знает, а может и нельзя =)

Автор: Domestic Cat 20.8.2004, 15:54
Цитата(redrick @ 19.8.2004, 19:09)
На мой взгляд это всё таки логичнее : вызывается конструктор базового класса, из него вызывается метод - естественно искать его в этом же классе, тем более, что в этот момент наследник ещё не создан. Хотя с другой стороны создатели Java тоже правы - вроде как дополнительная возможность, но вот нужна ли она ?


Хм, для чего? Кажется, вот для чего:

Код


class A
{
   public A()
   {
       initParsers();
       init();
       parseSomeStuff();
   }
   
   initParsers() { ... }
   init() { ... }
   parseSomeStuff() { ... }
}

class C extends A
{
   public C()
   {
       
   }
   
   init() { ... }
   
   parseSomeStuff() { ... }
}



Предположим, я вызываю A():

A() -> a.initParsers() -> a.init() -> a.parseSomeStuff()

Теперь C()

A() -> a.initParsers() -> c.init() -> c.parseSomeStuff() -> C()

Если я все-таки хочу вызвать a.init(), я вставлю super() в c.init().
А если я не хочу его вызвать? Здесь -то все просто, а в C++ нужно что сделать? По-моему, только переписать А, и соответственно, все классы от него наследующие.

//Я тут B класс удалил - он был лишний

Автор: redrick 20.8.2004, 16:07
хм, спору нет, но вот вообще в С++ сообществе считается хорошим тоном не заставлять конструктор делать что-то кроме своих прямых обязанностей, т. е. инициаллизации полей _начальными_, а не появляющимися в процессе работы значениями. Думаю, если и можно придумать пример, в котором это правило будет нарушено и нарушение оправдано, то это получится довольно натянуто. Неговоря уже о тяжелой воспринимаемости такого кода (нужно лишний раз соображать что и где вызовется). В вышеприведенном примере я бы вынес все эти действия в функцию типа init_0() и явно вызывал бы ее.

Автор: Domestic Cat 20.8.2004, 16:21
А что ж тут плохого? Я инициализирую суперкласс в init().
Для инициализации сабкласса мне нуzhно чо-то другое отпарсить, вот и все. Если учесть возможность того, что саблассы могут по-другому инициализировать поля, наследованные от суперкласса, то как раз все ок. Если не ошибаюсь, в C++ есть такая штука как
"resource acquisition is initialization". Да и вызов init() вполне нормальное
явление, см. Stroustrup, The C++ Programming Language, 2000, 14.4.1. Using Constructors
and Destructors.
init() , initParsers() могут инициализировать различные ресурсы, соответственно, можно один init() разбит' на несколько методов.

Автор: redrick 20.8.2004, 17:02
вобщем здесь я уже немного "не в теме", поэтому не буду говорить и утверждать глупостей, но вот у Страуструпа насколько я понял идет речь как раз об использовании ресурсов, ну то есть памяти, а когда вы парсите там что то, то это уже никак нельзя назвать просто захватом ресурсов.

И вот ещё (опять же на правах чистого имхо) : если ваш детёнок инициализирует поля родителя по-другому нежели родитель, то стоило ли его вообще делать детёнком этого родителя ?

Автор: Domestic Cat 20.8.2004, 17:18
Цитата(redrick @ 20.8.2004, 08:02)
если ваш детёнок инициализирует поля родителя по-другому нежели родитель, то стоило ли его вообще делать детёнком этого родителя ?


Например:
Код

class Submarine
{
   protected Engine engine;
   public Submarine()
   {
       init();
   }
   
   protected void init()
   {
       engine = new Engine();
   }
}
class NuclearSubmarine extends Submarine
{
   public NuclearSubmarine()
   {
   }
   
   protected void init()
   {
       engine = new NuclearEngine();
   }
}
class DieselSubmarine extends Submarine
{
   public DieselSubmarine()
   {
   }

   protected void init()
   {
       engine = new DieselEngine();
   }
}

class DieselSubmarineType2 extends DieselSubmarine
{
   public DieselSubmarineType2()
   {
   }
   
   protected void init()
   {
       engine = new DieselEngineType2();
   }
}
class DieselSubmarineType1 extends DieselSubmarine
{
   public DieselSubmarineType1()
   {
   }
   
   protected void init()
   {
       engine = new DieselEngineType1();
   }
}

Автор: Domestic Cat 20.8.2004, 17:30
Давайте вернемся к теме.

Вопрос: какие проблемы могут возникнуть при запуске программы:
Код


public class Test extends Thread
{
   int[] array;
   
   public Test()
   {
       run();
   }
   
   public void run()
   {
       array = new int[10000];
   }
   public static void main(String [] arg)
   {
       for (int i = 0; i < 10000; i ++)
       {
           new Test();
       }
   }
}

Автор: AntonSaburov 20.8.2004, 17:50
А эта строчка специально с пробелом (String []) ?
Цитата(Domestic @ 20.8.2004, 18:30)
public static void main(String [] arg)


А вообще 10000*10000 = 100 000 000 да еще на размер целого. Вывалится по нехватке памяти, если конечно опциями не добавить.

Автор: Domestic Cat 20.8.2004, 17:53
Цитата(AntonSaburov @ 20.8.2004, 08:50)
А эта строчка специально с пробелом (String []) ?


А разве на что-то влияет? smile.gif

Цитата(AntonSaburov @ 20.8.2004, 08:50)
А вообще 10000*10000 = 100 000 000 да еще на размер целого. Вывалится по нехватке памяти, если конечно опциями не добавить.


Хм. А сборщик мусора? Разве не должен он убирать все эти массивы? wink.gif
Добавлено @ 17:54
Ведь сразу после 1 пробега цикла ссылки на объект в памяти нет!

Автор: redrick 20.8.2004, 18:58
а сборщик мусора когда захочет, тогда и соберет - вовсе не обязательно сразуже

и вот еще такой вопрос : собственно где и какая ссылка на объект класса Test появляется после выполнения

new Test() ?

понятно, что эивет она в фигурных скобочках цикла только - но тогда, кстати, все объекты будут жить, пока цикл не закончится и GC нам тут уж никак не поможет

Автор: Domestic Cat 20.8.2004, 19:32
Цитата(redrick @ 20.8.2004, 09:58)
а сборщик мусора когда захочет, тогда и соберет - вовсе не обязательно сразуже


Если создается много объектов - он начнет работать. Зуб даю. Редиской буду.
Ну а проверить можно, запуская с флагом -verbose:gc. В данном случае сбоки мусора будут, но незначительные.

Цитата(redrick @ 20.8.2004, 09:58)
и вот еще такой вопрос : собственно где и какая ссылка на объект класса Test появляется после выполнения


А ее нету - прoграмма на объект не ссылается, следовательно , он подлежит сборке

Цитата(redrick @ 20.8.2004, 09:58)
понятно, что эивет она в фигурных скобочках цикла только - но тогда, кстати, все объекты будут жить, пока цикл не закончится и GC нам тут уж никак не поможет


Чтобы проверить, нужно поставить в цикл просто

int[] array = new int[10000];

и запустить с тем же флагом.
Уууупс smile.gif Не будут они жить smile.gif

Автор: redrick 20.8.2004, 23:02
насчет GC - ну это хорошо, но формально никаких гарантий нет и полагаться на это нельзя совсем. А то сделаем из Sun ещё один M$ (http://www.joelonsoftware.com/articles/APIWar.html)

а насчет времени жизни - это я ошибся, т. е. не знал =)

забавно получается - создаем объект и он сразу может умирать

Автор: Domestic Cat 21.8.2004, 23:04
В общем, проблема такая: если поставить в main

Код

...
System.out.println(Runtime.getRuntime().freeMemory());
for (int i = 0; i < 10000; i ++)
{
    new Test();
}
System.out.println(Runtime.getRuntime().freeMemory());
...


то окажется, что new Test() забивает память очень серьeзно; а gc работать и не собирается
(хотя он на самом деле чего-то собирает, по нескольку килобайт несколько раз smile.gif )

Заменим new Test() чем-нибудь другим- будь то new Object(), new Integer() или int[] arr = new int[10000] - все ок, в конце память почти не истрачена, да и gc трудится хорошо. Вопрос: почему? Подсказка n1 : в коде есть логическая ошибка. Но даже если ее найти, то почему gc не убирает мертвые объекты?

Автор: DarkDS 22.8.2004, 01:18
Цитата(Domestic @ 20.8.2004, 15:54)
Если я все-таки хочу вызвать a.init(), я вставлю super() в c.init().
А если я не хочу его вызвать? Здесь -то все просто, а в C++ нужно что сделать? По-моему, только переписать А, и соответственно, все классы от него наследующие.

Для этого в сях есть виртуальность smile.gif

Автор: Guest 23.8.2004, 09:49
Объекты не "мертвые". Они находятся в состоянии NEW.
GC не трогает объект класса Thread до тех пор, пока он не окажется в состоянии TERMINATED

Автор: AntonSaburov 23.8.2004, 12:44
Цитата(Guest @ 23.8.2004, 10:49)
Объекты не "мертвые". Они находятся в состоянии NEW.
GC не трогает объект класса Thread до тех пор, пока он не окажется в состоянии TERMINATED

А можно поподробнее - что-то я такого не встречал (все знать нельзя smile.gif ). Было бы крайне интересно.

Автор: Guest 23.8.2004, 14:50
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.State.html

http://www.codeguru.com/java/tij/tij0155.shtml#Heading483

When main( ) creates the Thread objects it isn’t capturing the handles for any of them. An ordinary object would be fair game for garbage collection, but not a Thread. Each Thread “registers” itself so there is actually a reference to it someplace and the garbage collector can’t clean it up until the thread exits its run( ) and dies

Автор: Domestic Cat 23.8.2004, 15:11
[
Цитата(Guest @ 23.8.2004, 05:50)
Объекты не "мертвые". Они находятся в состоянии NEW.
GC не трогает объект класса Thread до тех пор, пока он не окажется в состоянии TERMINATED


Таки Guest раскусил smile.gif Может зарегистрируешся?

А ошибка была в том, что вместо start() я вызывал run(), то есть поток запущен на самом деле не был smile.gif

Автор: Domestic Cat 23.8.2004, 15:42
Цитата(DarkDS @ 21.8.2004, 16:18)
Если я все-таки хочу вызвать a.init(), я вставлю super() в c.init().
А если я не хочу его вызвать? Здесь -то все просто, а в C++ нужно что сделать? По-моему, только переписать А, и соответственно, все классы от него наследующие.

Для этого в сях есть виртуальность


Можно написать виртуальный метод, инициализирующий поле и вызывать его после
конструктора, но как это сделать из конструктора?

Автор: Domestic Cat 23.8.2004, 18:41
Простой вопрос:

Напечатает ли эта программа "true"?

Код

public class Test
{
   public static void main(String [] arg)
   {
       char[][] array = new char[2][20];
       array[0][0] = 'a';
       array[0][1] = 'b';
       array[0][2] = 'c';
       
       String string = new String(array[0]);
       System.out.println(string.equals("abc"));
   }
}

Автор: redrick 23.8.2004, 19:23
на первый взгляд вроде бы не видно подводных камней...

Цитата

public String(char[] value)

Allocates a new String so that it represents the sequence of characters currently contained in the character array argument. The contents of the character array are copied; subsequent modification of the character array does not affect the newly created string.



Цитата

public boolean equals(Object anObject)

Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.


с массивом вроде тоже всё чисто - "array of array of char"

т. е. ответ "да"

Автор: Domestic Cat 23.8.2004, 19:24
Остается ее запустить smile.gif

Автор: redrick 23.8.2004, 21:23
ёлки палки - как же я не заметил !!! (char[2][20];)

мда, лопухнулся так лопухнулся =))

Автор: Guest 23.8.2004, 21:25
Массивы примитивов при создании заполняются нулевыми значениями.
Строка из такого массива получится "соответствующая"

Код
   
byte[] bytes = string.getBytes();
for(int i=0;i<bytes.length;i++){
  System.out.println(i + " => " + (bytes[i] & 0xFF));
}

Автор: Domestic Cat 23.8.2004, 21:33
А что нужно сделать, чтобы получить в результате true; но при этом string менять нельзя?

Автор: redrick 23.8.2004, 21:55
ну например так...

Код

System.out.println(string.startsWith("abc"));

Автор: Domestic Cat 23.8.2004, 21:59
Можно, но это вызов метода... smile.gif А самый эффективный способ?

Автор: redrick 23.8.2004, 22:04
ну это уже загадки какие-то пошли =) А что собственно можно менять ?

System.out.println("true");

и всё =)

Автор: Domestic Cat 23.8.2004, 22:19
Аааа smile.gif , я бы предложил вариант:

Код

System.out.println(string.equals("abc\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000
0\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"));

Автор: redrick 23.8.2004, 22:26
=)

Идея в том, что пробелы не покатят ?

ну в общем понятно

Автор: Domestic Cat 24.8.2004, 15:46
Эта программа напечатает 96.985954:

Код

public class Test
{
   public static void main(String [] arg)
   {
       int x = 34527;
       int y = 356;
       System.out.println((float) x / y);
   }
}


Задача: изменить только ОДИН символ таким образом, чтобы она выдала 145.07143.

// под "изменить" подразумевается также и "добавить" и "удалить"

Автор: anonymouse 24.8.2004, 16:04
public class Test
{
public static void main(String [] arg)
{
int x = 34527;
int y = 0356;
System.out.println((float) x / y);
}
}

smile.gif

Автор: redrick 24.8.2004, 16:14
вообще говоря это не изменение, а дополнение - ну это конечно не суть =)

Автор: Domestic Cat 24.8.2004, 16:21
Цитата(anonymouse @ 24.8.2004, 07:04)
public class Test
{
public static void main(String [] arg)
{
int x = 34527;
int y = 0356;
System.out.println((float) x / y);
}
}


Быстро, однако thumbs-up.gif


Автор: Domestic Cat 24.8.2004, 16:57
Простой:
Код

import java.util.*;

public class Test
{
   public static void main(String [] arg)
   {
       Calendar calendar = Calendar.getInstance();
       calendar.set(Calendar.DAY_OF_MONTH, 2334);
       System.out.println("Date is : " + calendar.get(Calendar.DATE));
   }
}


1. Почему дата будет 21?
2. Что нужно добавить, чтобы нельзя было использовать "неправильные" даты?

Автор: anonymouse 24.8.2004, 17:31
1. потому как день в месяце будет высчитываться 2334 % 365(дней в году) % 31(макс. дней в месяце) + 1(первое число).
2. сделать можно все что угодно, а какие ограничения ?

Автор: Domestic Cat 24.8.2004, 17:40
Ок, ограничeния такие:
1. Нельзя проверять дату (например : if (date > 31) {...})
2. Нельзя бросать эксепшн
3. Нельзя устанавливать / читать дату соответствуюшими методами get / set.

Автор: anonymouse 24.8.2004, 17:51
нашел smile.gif :

calendar.setLenient(false);

Автор: AntonSaburov 24.8.2004, 18:08
Думаю, что несложно, но ...
Как можно объявить несколько public классов в одном файле ?

Автор: Domestic Cat 24.8.2004, 18:28
Цитата(anonymouse @ 24.8.2004, 08:51)
нашел  :

calendar.setLenient(false);

Ага, хороший метод smile.gif

Цитата(AntonSaburov @ 24.8.2004, 09:08)
Как можно объявить несколько public классов в одном файле ?

Сделать их внутренними?

Автор: AntonSaburov 24.8.2004, 18:37
Цитата(Domestic @ 24.8.2004, 19:28)
Сделать их внутренними?

Ага. Только можно уточнить чтоюы можно было объявить переменные такого типа в других классах ?

Автор: Domestic Cat 24.8.2004, 18:43
В смысле, так : ?
Код


// Test.java
public class Test
{
   public static void main(String [] args)
   {
       A a  = new A();
       A.B b = a.new B();
   }
}

// A.java
public class A
{
   public class B
   {
       public B()
       {
           System.out.println("A$B");
       }
   }
}


Автор: anonymouse 24.8.2004, 18:48
а если так
// A.java
public class A
{
public static class B
{
public B()
{
System.out.println("A$B");
}
}
}
то и A не надо будет инициализировать

// Test.java
public class Test
{
public static void main(String [] args)
{
A a = new A();
A.B b = new A.B();
}
}

Автор: AntonSaburov 24.8.2004, 18:52
Ок. Что выведет такой код

Код

public class Test
{
 public static void main(String[] args)
 {
   byte ba = 120;
   byte bb = 120;
   int ia = 2000000000;
   int ib = 2000000000;
   long la = 2000000000;
   long lb = 2000000000;

   System.out.println(ba+bb);
   System.out.println(ia+ib);
   System.out.println(la+lb);
 }
}


Желательно объяснить результат smile.gif

Автор: Domestic Cat 24.8.2004, 18:52
Цитата(anonymouse @ 24.8.2004, 09:48)
то и A не надо будет инициализировать


А это зависит от того, что нужно. Если нужно чтобы каждый объект класса А
ассоциировался с объектом класса B, то используем внутренний класс (member class),
а если просто два "близких по смыслу" класса - то static member class.

Добавлено @ 19:02


Цитата(AntonSaburov @ 24.8.2004, 09:52)
Ок. Что выведет такой код

Размер у лонга приличный, так что последний принт даст 4000000000
Первый даст 240, поскольку для байтов метода System.out.println() нет, и произойдет конвертация в int.
А второй принт даст что-то отрицательное из-за оверфлова.

Автор: Domestic Cat 24.8.2004, 19:25
Задача: написать программу, которая через час начнет выдавать сообщения типа
"Wake Up !!!" smile.gif (будильник).
Программа должна занимать 1 строчку (не считая импортов, public class.., public static void main ... и скобок).
Строчкой cчитаем все, что заканчивается точкой с запятой (кроме ";" во внутренних классах).
Наследовать от класса Thread и интерфейса Runnable нельзя. Использовать методы классa Thread нельзя.

Автор: AntonSaburov 24.8.2004, 20:09
Зацепило smile.gif Правда я для примера не стал так уж долго, но тут только время побольше поставить.

Код

import java.util.*;

public class Focus
{
 public static void main(String[] args)
 {
   new Timer().schedule(
     new TimerTask() {
       public void run()
       {
         System.out.println("Wake up!");
       }
     }, 2000, 1000);
 }
}

Автор: Domestic Cat 24.8.2004, 20:24
У меня аналогичный вариант smile.gif

Ну а такая : Написать код в одну строчку (определение строчки такое же как и выше),
который будет отлавливать все AWTEvent'ы и печатать их в консоль.

Автор: Domestic Cat 25.8.2004, 16:10
Код

Toolkit.getDefaultToolkit().addAWTEventListener(
  new AWTEventListener() {
      public void eventDispatched(AWTEvent e)
      {
            System.out.println(e);
      }
  }
, -1);

Автор: Domestic Cat 25.8.2004, 20:10
Если к числу прибавить 256, то получится 123.
Если его умножить на 2, то получим -10.

Что это за число? Решать в уме. smile.gif

Автор: DarkDS 25.8.2004, 22:47
А какого типа число? smile.gif

Автор: DarkDS 25.8.2004, 23:03
Хотя я понял smile.gif Нужно и тип определить smile.gif
Это будет байт = 123

Автор: Domestic Cat 26.8.2004, 15:42
smile.gif

Код

int y = 0;
if (x&y == 0) System.out.println("...");


что нужно дописать, чтобы код скомпилился? Сам код не менять.

Автор: DarkDS 26.8.2004, 16:28
Код
if ((x&y) == 0) System.out.println("...");

Автор: Domestic Cat 26.8.2004, 16:57
Цитата(Domestic @ 26.8.2004, 06:42)
Сам код не менять.



exclamation.gif exclamation.gif exclamation.gif

Автор: AntonSaburov 26.8.2004, 17:07
boolean x = false;

Автор: Domestic Cat 26.8.2004, 17:10
Слишом простые вопросы smile.gif smile.gif smile.gif

Автор: AntonSaburov 27.8.2004, 11:17
Цитата(Domestic @ 26.8.2004, 18:10)
Слишом простые вопросы

Ну это же не только для хорошо знающих - пусть и начинающие подключаются. Я собирался недели через две уже начать делать выжимку из этого топика. А этот пусть остается smile.gif

Автор: Domestic Cat 27.8.2004, 15:24
[/code]
Цитата(AntonSaburov @ 27.8.2004, 02:17)
Я собирался недели через две уже начать делать выжимку из этого топика.


В смысле? adv/eek.gif

-----

Продолжу простые вопросы:
Что напечатает код и почему:

Код

public class Test
{
   public static void main(String [] rr)
   {
       if("String".toString() == "String")
           System.out.println("Equal");
       else
           System.out.println("Not Equal");
   }
}

Автор: AntonSaburov 27.8.2004, 16:54
Цитата(Domestic @ 27.8.2004, 16:24)
В смысле?

Я поначалу хотел просто убрать водичку, но с другой стороны тут общение живое - мне нравиться, не хотелось, чтобы исчез некий дух smile.gif
Вот и подумал - может делать это в отдельном топике. А здесь все как раньше.

Очень хороший топик получается biggrin.gif
Добавлено @ 17:00
А я не угадал - но почему они Equal ?

Похоже, тут оптимизация работает, но у меня нет уверенности. А хотелось бы точно знать

Автор: Domestic Cat 27.8.2004, 17:17
Цитата(AntonSaburov @ 27.8.2004, 07:54)
А я не угадал - но почему они Equal ?

Подсказка: smile.gif smile.gif
Код

String a = "java";      
String b = "java";
System.out.println(a == b);


Код

String a = new String("java");      
String b = new String("java");
System.out.println(a == b);



Автор: redrick 28.8.2004, 02:15
когда константой инициализируется, то один и тот же объект подставляется (соответственно и хеши одинаковые) - это и правда оптимизация (вдруг они только для чтения будут использоваться). А если придет запрос на запись в a или b то создастся новый объект с таким же содержимым.

для полноты картины отискал вот :


Java Language Specification
Second Edition

Цитата

3.10.5 String Literals
A string literal consists of zero or more characters enclosed in double quotes. Each character may be represented by an escape sequence.
A string literal is always of type String (§4.3.3. A string literal always refers to the same instance (§4.3.1) of class String.


StringLiteral:
" StringCharactersopt "

StringCharacters:
StringCharacter
StringCharacters StringCharacter

StringCharacter:
InputCharacter but not " or \
EscapeSequence

The escape sequences are described in §3.10.6.
As specified in §3.4, neither of the characters CR and LF is ever considered to be an InputCharacter; each is recognized as constituting a LineTerminator.

It is a compile-time error for a line terminator to appear after the opening " and before the closing matching ". A long string literal can always be broken up into shorter pieces and written as a (possibly parenthesized) expression using the string concatenation operator + (§15.18.1).

The following are examples of string literals:

""    // the empty string
"\""    // a string containing " alone
"This is a string"  // a string containing 16 characters
"This is a " +  // actually a string-valued constant expression,
"two-line string" //  formed from two string literals

Because Unicode escapes are processed very early, it is not correct to write "\u000a" for a string literal containing a single linefeed (LF); the Unicode escape \u000a is transformed into an actual linefeed in translation step 1 (§3.3) and the linefeed becomes a LineTerminator in step 2 (§3.4), and so the string literal is not valid in step 3. Instead, one should write "\n" (§3.10.6). Similarly, it is not correct to write "\u000d" for a string literal containing a single carriage return (CR). Instead use "\r".

Each string literal is a reference (§4.3) to an instance (§4.3.1, §12.5) of class String (§4.3.3). String objects have a constant value. String literals-or, more generally, strings that are the values of constant expressions (§15.28)-are "interned" so as to share unique instances, using the method String.intern.
Thus, the test program consisting of the compilation unit (§7.3):

package testPackage;
class Test {
public static void main(String[] args) {
  String hello = "Hello", lo = "lo";
  System.out.print((hello == "Hello") + " ");
  System.out.print((Other.hello == hello) + " ");
  System.out.print((other.Other.hello == hello) + " ");
  System.out.print((hello == ("Hel"+"lo")) + " ");
  System.out.print((hello == ("Hel"+lo)) + " ");
  System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }

and the compilation unit:

package other;
public class Other { static String hello = "Hello"; }

produces the output:

true true true true false true

This example illustrates six points:

Literal strings within the same class (§8) in the same package (§7) represent references to the same String object (§4.3.1).
Literal strings within different classes in the same package represent references to the same String object.
Literal strings within different classes in different packages likewise represent references to the same String object.
Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.
Strings computed at run time are newly created and therefore distinct.
The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)