Lecture11 (1133568), страница 5
Текст из файла (страница 5)
Если классисключения не наследует одному из этихклассов, оно считается проверяемым.Все классы проверяемых исключений,возникновение которых возможно при работеметода, должны быть описаны в его заголовкепосле ключевого слова throws.Если некоторый метод вызывает другой,способный создать проверяемое исключениетипа T, то либо этот вызов должен быть врамках try-блока, для которого имеетсяобработчик исключений типа T или болееобщего типа, либо вызывающий метод тожедолжен указать тип T или более общий средитипов исключений, возникновение которыхвозможно при его работе.public void m(int x)throws MyException{throw new MyException();}public void n(int x)throws MyException{m(x);}public void k(int x){try { m(x); }catch(MyException e){ ...
}}В Java все параметры операций передаются позначению.Поскольку все типы, кроме примитивных,являются ссылочными, значения таких типов —ссылки на объекты. При выполнении операцииможно изменить состояние объекта,переданного ей в качестве параметра, но нессылку на него.В C# можно определить параметры операций,передаваемые по ссылке, и выходныепараметры операций.Параметры, передаваемые по ссылке,помечаются модификаторов ref. Выходныепараметры помечаются модификатором out.При вызове операции значения этих параметровдолжны быть помечены так же.using System;public class A{public void f(int a, ref int b, out int c){c = b - a;b += a;}public static void Main(){A a = new A();int n = 3, m = 0;Console.WriteLine("n = " + n + " , m = " + m);a.f(1, ref n, out m);Console.WriteLine("n = " + n + " , m = " + m);}}Описание метаданныхВ обоих языках (в Java — начиная с версии 5) имеются встроенные средства для некоторого ихрасширения, для описания так называемых метаданных — данных, описывающих элементы кода.Это специальные модификаторы у типов, элементов типов и параметров операций, называемые вJava аннотациями (annotations), а в C# — атрибутами (attributes).
Один элемент кода можетиметь несколько таких модификаторов.Такие данные служат для указания дополнительных свойств классов, полей, операций ипараметров операций. Например, можно пометить специальным образом поля класса, которыедолжны записываться при преобразовании объекта этого класса в поток байтов длядолговременного хранения или передачи по сети. Можно пометить методы, которые должныработать только в рамках транзакций или, наоборот, только вне транзакций.Метаданные служат встроенным механизмом расширения языка, позволяя описывать простыедополнительные свойства сущностей этого языка в нем самом, не разрабатывая каждый разспециализированные трансляторы.
Обработка метаданных должна, конечно, осуществлятьсядополнительными инструментами, но такие инструменты могут быть достаточно просты — им ненужно реализовывать функции компилятора исходного языка.В обоих языках аннотации могут иметь структуру — свойства или параметры, которым можноприсваивать значения. Эту структуру можно определить в описании специальногоаннотационного типа.В приведенных ниже примерах определяются несколько типов аннотаций, которые затемиспользуются для разметки элементов кода.
Класс A помечен аннотацией, имеющей указанныезначения свойств, оба метода помечены простой аннотаций (указывающей, например, что такойметод должен быть обработан особым образом), кроме того, метод n() помечен еще однойаннотацией.
Параметр метода n() также помечен простой аннотацией.@interface SimpleMethodAnnotation {}class SimpleMethodAttribute: Attribute{}@interface SimpleParameterAnnotation{}class SimpleParameterAttribute: Attribute{}@interface ComplexClassAnnotation{class ComplexClassAttribute: Attribute{public int id;public String author ="Victor Kuliamin";public String date;}int id();String author() default"Victor Kuliamin";String date();}}class AdditionalMethodAttribute: Attribute{public String value = "";}@ComplexClassAnnotation(id= 126453,date= "23.09.2005")public class A{@SimpleMethodAnnotationpublic void m() { ... }[ComplexClassAttribute(id= 126453,date= "23.09.2005")]public class A{[SimpleMethodAttribute]public void m() { ... }@interface AdditionalMethodAnnotation{String value() default "";@SimpleMethodAnnotation@AdditionalMethodAnnotation( value = "123" )public void n(@SimpleParameterAnnotation int k){ ...
}[SimpleMethodAttribute,AdditionalMethodAttribute(value = "123")]public void n([SimpleParameterAttribute] int k){ ... }}}В Java аннотации могут помечать также пакеты(т.е. использоваться в директиве декларациипакета, к которому относится данный файл),декларации локальных переменных и константыперечислимых типов.В C# могут быть описаны глобальные атрибуты,помечающие сборку, в рамках кода которой онивстречаются.
Такие атрибуты помещаются внеописаний пространств имен.Также атрибутами могут помечаться отдельныеметоды доступа к свойствам, индексерам исобытиям.Атрибутный тип описывается как класс,Аннотационный тип декларируется смодификатором @interface и неявно наследуетинтерфейсуjava.lang.annotation.Annotation.Такой тип не может иметь типовых параметровили явным образом наследовать другому типу.Свойства аннотационного типа описываютсякак абстрактные методы без параметров, свозможным значением по умолчанию.При определении значений свойств аннотациичерез запятую перечисляются пары <имясвойства> = <значение>.Помимо свойств, в аннотационном типе могутбыть описаны константы (public staticfinal поля) и вложенные типы, в том числеаннотационные.наследующий System.Attribute или егонаследнику.Такой тип не может иметь типовых параметров.Свойства атрибутного типа могут бытьименованными параметрами и позиционнымипараметрами.Позиционные параметры определяются припомощи конструкторов атрибутного типа.Именованные параметры определяются какдоступные для чтения и записи нестатическиеполя и свойства атрибутного типа.При определении значений свойств атрибутасначала через запятую перечисляются значенияпозиционных параметров, а затем пары <имяименованного параметра> = <значение>.В атрибутном типе могут быть описаны такиеже элементы, как и в обычном классе.Ниже приведен пример использованияпозиционного параметра.class ClassAttribute : Attribute{public ClassAttribute(int id){this.id = id;}int id;public string value;}[ClassAttribute(4627, value = "")]public class A { ...
}Свойство аннотационного типа может иметьпримитивный тип, тип String, Class,экземпляр шаблонного типа Class,перечислимый тип, аннотационный тип илибыть массивом элементов одного изперечисленных типов.Свойство атрибутного типа может иметь одиниз типов bool, byte, char, double, float, int,long, short, string, object, System.Type,перечислимый тип или быть массивомэлементов одного из таких типов.У атрибутов может указываться цель, к которойони привязываются. Для атрибутов,помещаемых вне рамок пространств имен,указание такой цели — assembly —обязательно.[assembly :MyAttribute(id = 4627,author = "Victor Kuliamin")]В C# принято соглашение, согласно которомуокончание Attribute в именах атрибутныхтипов может отбрасываться при использованииатрибутов такого типа.Поэтому, имея атрибутный типClassAttribute, можно использовать ватрибутах как полное имя ClassAttribute, таки сокращенное Class.В последнем случае компилятор будет пытатьсянайти атрибутный тип с именем Class или сименем ClassAttribute.
При этом возможнанеоднозначность — оба таких типа могутсуществовать в рамках сборки и доступныхбиблиотек. Для ее разрешения можноиспользовать точное имя атрибутного типа спрефиксом @. Увидев атрибут @Class,компилятор будет искать атрибутный тип вточности с именем Class.Средства создания многопоточных программКак в Java, так и в C# возможно создание многопоточных приложений. Вообще говоря, каждаяпрограмма на этих языках представляет собой набор потоков (threads), выполняющихсяпараллельно. Каждый поток является исполняемым элементом, имеющим свой собственный потокуправления и стек вызовов операций. Все потоки в рамках одного процесса (одной виртуальноймашины Java или одного процесса среды .NET) имеют общий набор ресурсов, общую память,общий набор объектов, с которыми могут работать.Каждый поток представляется в языке объектом некоторого класса (java.lang.Thread в Java иSystem.Threading.Thread в C#).
Для запуска некоторого кода в виде отдельного потоканеобходимо определить особую операцию в таком объекте и выполнить другую его операцию.В Java это можно сделать двумя способами.Первый — определить класс-наследникjava.lang.Thread и перегрузить в этом классеметод public void run(). Этот метод,собственно и будет выполняться в видеотдельного потока.Другой способ — определить класс,реализующий интерфейс java.lang.Runnable иего метод void run(). После чего построитьобъект класса Thread на основе объекта толькочто определенного класса.В обоих случаях для запуска выполненияпотока нужно вызвать в объекте класса Thread(в первом случае — его наследника) метод voidstart().В C# также можно использовать два способа.
Спомощью первого можно создать обычныйпоток, с помощью второго — поток, которомупри запуске нужно передать какие-то данные.Для этого нужно определить метод, которыйбудет выполняться в рамках потока. Этот методдолжен иметь тип результата void. Список егопараметров в первом случае должен бытьпустым, во втором — состоять из одногопараметра типа object.В первом варианте на основе этого методасоздается делегат типаSystem.Threading.ThreadStart, во втором —типа System.Threading.ParameterizedThreadStart.Этот делегат передается в качестве аргументаконструктору объекта класса System.Thread.Поток запускается выполнением методаStart() у объекта класса Thread в первомслучае, или метода Start(object) во втором.using System;using System.Threading;class T extends Thread{int id = 0;public T(int id){ this.id = id; }class T{int id;public T(int id){ this.id = id; }public void m(){Console.WriteLine("Thread " + id + " is working");}public void run(){System.out.println("Thread " + id + " is working");}}}public class A{public static void main(String[] args){Thread th1 = new T(1),th2 = new T(2),th3 = new Thread(new Runnable() {public void run(){System.out.println("Runnable is working");}});public class A{static void m(){Console.WriteLine("Nonparameterized thread" +" is working");}static void m(object o){Console.WriteLine("Thread with object " + o +" is working");}th1.start();th2.start();th3.start();public static void Main(){Thread th1 = new Thread(new ThreadStart(m)),th2 = new Thread(new ThreadStart(new T(1).m)),th3 = new Thread(new ParameterizedThreadStart(m));}}th1.Start();th2.Start();th3.Start(2);}}При разработке приложений, основанных на параллельном выполнении нескольких потоков,большое значение имеют вопросы синхронизации работы этих потоков.